0. ๋ค์ด๊ฐ๊ธฐ ์ ์
MapStruct๋ Entity์ Dto๊ฐ์ ๋งคํ์ ์ง์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
Entity์ Dto๊ฐ์ ๋งคํ์ ์ํด getter/setter๋ฅผ ๋จ๋ฐํ๋ฉฐ ์ง์ ๊ตฌํํ๋ ๊ฒ์ ์ง์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํฌ๊ฒ ModelMapper์ MpaStruct๊ฐ ์๋ค.
์ฃผ๋ก ์ฐ์ด๋ ModelMapper์ ๋น๊ตํ์๋, MapStruct๋ ์ปดํ์ผ์ ๋ฏธ๋ฆฌ ์์ฑ๋ ๊ตฌํ์ฒด๋ฅผ ํตํด Mappingํ๊ธฐ ๋๋ฌธ์ ์๋์ ์ธ ์ธก๋ฉด์์ ์ด์ ์ด ์์ด ์ฑํํ๋ค.
ํ๋ก์ ํธ์ MapStruct๋ฅผ ์ฌ์ฉํด ๊ฐ๋จํ ์ฌ์ฉ๊ธฐ๋ฅผ ๊ธฐ๋กํ๋ค.
\
1. ํ๊ฒฝ์ค์
Gradle์ ๋ค์๊ณผ ๊ฐ์ด dependencies๋ฅผ ์ค์ ํ๋ค
\
implementation 'org.mapstruct:mapstruct:1.4.1.Final'
implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
implementation "org.projectlombok:lombok:1.18.16"
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.1.Final"
annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
annotationProcessor "org.projectlombok:lombok:1.18.16"
\
2. MapStruct ์ ์ฉ
MapStruct๋ฅผ ์ ์ฉํ๊ธฐ ์ํด Generic์ ์ฌ์ฉํด ๋ฏธ๋ฆฌ interface๋ฅผ ๋ง๋ ๋ค
GenericMapper interface
public interface GenericMapper<D, E> {
D toDto(E e);
E toEntity(D d);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateFromDto(D dto, @MappingTarget E entity);
}
updateFromDto()๋ ๊ธฐ์กด ์์ฑ๋์ด์๋ Entity๋ฅผ ์
๋ฐ์ดํธํ๊ณ ์ถ์ ๋ null์ด ์๋ ๊ฐ๋ง ์
๋ฐ์ดํธํ ์ ์๋ค.
@MappingTarget
: ๋ณํํ์ฌ ๊ฐ์ฒด๋ฅผ returnํ๋ ๊ฒ์ด ์๋ ์ธ์๋ก ๋ฐ์ ์
๋ฐ์ดํธํ target์ ์ค์ ํ๋ค.
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
Source์ ํ๋๊ฐ null์ผ ๋ ์ ์ฑ
์ผ๋ก null์ธ ๊ฐ์ ๋ฌด์ํ๋ค.
์ด์ ์ด GenericMapper์ ์์๋ง ๋ฐ์ ๋ค @Mapper
๋ง ์ ์ธํด์ฃผ๋ฉด ๋๋ค.
\
CodingRoomMapper interface
@Mapper(componentModel = "spring")
public interface CodingRoomMapper extends GenericMapper<CodingRoomDto, CodingRoom> {
}
@Mapper
: MapStruct Code Generator๊ฐ ํด๋น ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ์์ฑํด์ค๋ค.
componentModel = "spring"
: spring์ ๋ง๊ฒ bean์ผ๋ก ๋ฑ๋กํด์ค๋ค
\
CodingRoomMapperImpl class
\
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-05-28T02:50:51+0900",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
)
@Component
public class CodingRoomMapperImpl implements CodingRoomMapper {
@Override
public CodingRoomDto toDto(CodingRoom arg0) {
if ( arg0 == null ) {
return null;
}
CodingRoomDto codingRoomDto = new CodingRoomDto();
if ( arg0.getKey() != null ) {
codingRoomDto.setKey( String.valueOf( arg0.getKey() ) );
}
codingRoomDto.setTitle( arg0.getTitle() );
codingRoomDto.setIntro( arg0.getIntro() );
codingRoomDto.setPassword( arg0.getPassword() );
codingRoomDto.setMaxUser( arg0.getMaxUser() );
codingRoomDto.setRamdomKey( arg0.getRamdomKey() );
codingRoomDto.setCreatedAt( arg0.getCreatedAt() );
codingRoomDto.setCodingJoinUsers( codingJoinUserListToCodingJoinUserDtoList( arg0.getCodingJoinUsers() ) );
codingRoomDto.setCodingTests( codingTestListToCodingTestDtoList( arg0.getCodingTests() ) );
return codingRoomDto;
}
@Override
public CodingRoom toEntity(CodingRoomDto arg0) {
if ( arg0 == null ) {
return null;
}
CodingRoom codingRoom = new CodingRoom();
if ( arg0.getKey() != null ) {
codingRoom.setKey( Long.parseLong( arg0.getKey() ) );
}
codingRoom.setTitle( arg0.getTitle() );
codingRoom.setIntro( arg0.getIntro() );
codingRoom.setPassword( arg0.getPassword() );
codingRoom.setMaxUser( arg0.getMaxUser() );
codingRoom.setRamdomKey( arg0.getRamdomKey() );
codingRoom.setCreatedAt( arg0.getCreatedAt() );
codingRoom.setCodingJoinUsers( codingJoinUserDtoListToCodingJoinUserList( arg0.getCodingJoinUsers() ) );
codingRoom.setCodingTests( codingTestDtoListToCodingTestList( arg0.getCodingTests() ) );
return codingRoom;
}
...
}
buildํ๋ค๋ฉด @Mapper๊ฐ ๋ถ์ interface์ ๋ํ ๊ตฌํ์ฒด๊ฐ ์๋ ์์ฑ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
\
CodingRoomService class
\
@Service
@RequiredArgsConstructor
public class CodingRoomService {
private final CodingRoomMapper codingRoomMapper;
...
CodingRoomDto codingRoomDto = codingRoomMapper.toDto(codingRoom);
...
}
๊ฐ ๊ตฌํ์ฒด๋ฅผ ๋ฐ์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
\
์ฐธ์กฐ ์ฌ์ดํธ