MapStruct

0. ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—


MapStruct๋Š” Entity์™€ Dto๊ฐ„์˜ ๋งคํ•‘์„ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

Entity์™€ Dto๊ฐ„์˜ ๋งคํ•‘์„ ์œ„ํ•ด getter/setter๋ฅผ ๋‚จ๋ฐœํ•˜๋ฉฐ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํฌ๊ฒŒ ModelMapper์™€ MpaStruct๊ฐ€ ์žˆ๋‹ค.

์ฃผ๋กœ ์“ฐ์ด๋Š” ModelMapper์™€ ๋น„๊ตํ–ˆ์„๋•Œ, MapStruct๋Š” ์ปดํŒŒ์ผ์‹œ ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋œ ๊ตฌํ˜„์ฒด๋ฅผ ํ†ตํ•ด Mappingํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„์ ์ธ ์ธก๋ฉด์—์„œ ์ด์ ์ด ์žˆ์–ด ์ฑ„ํƒํ–ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์— MapStruct๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๊ธฐ๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.

  • ๊ฐœ๋ฐœํ™˜๊ฒฝ

    • IntelliJ 2020.2

    • Java 8

    • SpringBoot 2.4.2

    • Gradle 6.8.2

\

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);
    ...        
    }
    

๊ฐ ๊ตฌํ˜„์ฒด๋ฅผ ๋ฐ›์•„์™€ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

\


์ฐธ์กฐ ์‚ฌ์ดํŠธ

profile\

Last updated