DTO, Entity간의 매핑을 간편하게 할 수 있도록 지원해주는 라이브러리다.
@Mapper
를 사용하고 @Mapping
으로 컬럼에 대한 추가적인 설정을 해주면 컴파일 시, MapperImpl
을 생성해준다.
리플렉션: 구체적인 클래스 타입을 알지 못해도, 그 클랙스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API
MapStruct를 자세히 알아보기 전에 기존의 Mapping 방법을 알아보자.
기존 DTO와 Entity간의 매핑 방법은 객체 생성 후, setter사용
, @Builder사용
, ModelMapper
가 있다. 본인은 그 중 @Builder
를 이용했다.
//DTO/Entity에 @Builder 선언 후,
RecordDto.builder().
.id(Record.getId())
.name(Record.getName())
.myTreeId(Record.getMyItemId())
.build();
위 방법은 필드가 많아진다면 꽤나 코드가 길어지고 그만큼 실수할 가능성이 생긴다.
Gradle에 mapstruct에 대한 dependencies를 설정한다
dependencies {
// lombok
implementation 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' // v1.18.16+ 부터
// mapstruct
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
Generic을 이용해서 MapStruct를 위한 인터페이스를 구현한다.
본인은 보통 이런 파일은 /global/common/mapper 폴더를 생성해서 여기에 작성한다.
public interface EntityMapper<D, E> {
E toEntity(final D dto);
D toDto(final E entity);
}
Product에 대한 Mapper을 작성해보겠다.
예시) RecordDto는 필드로 id, name, itemId, myItemid을 갖는다. MyItem은 itemId를 필드로 갖는다.
@Mapper
public interface RecordMapper extends EntityMapper<RecordDto, Record> {
RecordMapper mapper = Mappers.getMapper(RecordMapper.class);
@Override
@Mapping(target = "userId", ignore = true)
@Mapping(source = "myItem.item.id", target = "itemId")
@Mapping(source = "myItem.id", target = "myItemId")
RecordDto toDto(final Record entity);
@Override
@Mapping(source = "itemId", target = "myItem.item.id")
@Mapping(source = "myItemId", target = "myItem.id")
Record toEntity(final RecordDto dto);
}
ignore
하거나 따로 설정한다.컴파일 시, build폴더에 MapperImpl이 생성된다. ServiceImpl에서 해당 MapperImpl을 사용하면 된다.
여기서 @Mapping 설정에 따라 Entity->DTO 변환 시, userId는 null로 들어간다.
* userId와 같이 보안에 신경써야 하는 필드는 ignore설정을 해주는 것이 좋다.
//DTO(recordDto) <-> Entity(record)
RecordDto recordDto= RecordMapper.mapper.toDto(record);
Record record= RecordMapper.mapper.toEntity(recordDto);
정책을 ERROR로 설정하지 않았으면 컴파일 시, 에러코드가 출력되지만 에러가 발생하는 필드를 제외하고 MapperImpl
이 생성된다. 따라서 후에 MapperImpl
이 존재하기 때문에 프로그램이 중단되지 않고 그대로 작동된다. 이 MapperImpl
은 정상적인 작동을 하는 클래스가 아니니 이를 인지하고 있도록 하자
이를 방지하기 위해 정책을 Error로 설정해 오류가 있으면 파일 생성을 중단시킬 수 있다.
In the defender position, Como brought in quality defenders in Raphaël Varane and Alberto Moreno. Varane was recruited from Manchester United, while Moreno came from Villarreal. They arrived on free transfers.
https://www.nobartv.co.id/berita-terkini
https://en.nobartv.co.id/berita-terkini
https://ko.nobartv.co.id/berita-terkini
https://ja.nobartv.co.id/berita-terkini
https://ar.nobartv.co.id/berita-terkini
Varane's champion mentality is certainly not in doubt, because he was with the French National Team when they won the 2018 World Cup. When he was still with Real Madrid, Varane was even able to collect 18 titles, including 4 Champions League (UCL) trophies. While Moreno has 1 UCL trophy with Liverpool, and 2 Europa Leagues with Sevilla and Villarreal.
https://hi.nobartv.co.id/berita-terkini
https://ru.nobartv.co.id/berita-terkini
https://es.nobartv.co.id/berita-terkini
https://th.nobartv.co.id/berita-terkini
https://fr.nobartv.co.id/berita-terkini
Como also brought in Andrea Dossena from Cagliari. The three of them complete the back line alongside Marco Sala, Edoardo Goldaniga, Felipe Jack, Peter Kováčik, Tommaso Cassandro and Federico Barba.