Dto 와 Entity 변환을 라이브러리를 이용해 손쉽게 해봅니다.
MapStruct 를 이용합니다.
Goal
- MapStruct 라이브러리를 이용해
DTO <-> Entity
변환을 해봅니다.
의존성 추가
1 |
|
전체 Gradle
1 |
|
Entity와 DTO 구현
Member관련 DTO와 Entity 클래스를 만듭니다.
1 |
|
1 |
|
- From 쪽은 반드시 Getter를 만들어야 합니다. (Entity to DTO의 경우 From은 Entity가 됩니다.)
To 쪽은 반드시 Setter 혹은 Builder를 만들어야 합니다.-
제공되는 생성자만으로 인스턴스 생성에 문제가 없다면, Setter, Builder가 없어도 사용가능합니다.
- 먼저 롬복을 이용해 Builder를 만들어주었습니다.
- 둘의 차이가 있다면 DTO의 경우에는 id가 없지만, Entity에는 id가 있습니다.
Entity Mapper 인터페이스 구현
1 |
|
- Entity와 DTO로 변환시켜줄 상위 인터페이스를 만들어주었습니다.
1 |
|
1 |
|
- 본체는
MemberMapper
인터페이스 입니다. - 오버라이딩 한부분은, 디폴트로 값을 넣어주고 싶은 경우에 사용합니다.
- 해당 부분을 생략한다면, DTO to Entity과정에서 id값에는 null값이 들어가게 됩니다.
사용법
1 |
|
- 위처럼 사용하면
DTO <-> Entity
변환이 자유롭게 됩니다.
테스트
1 |
|
- 동등성을 검증하는데 사용한
usingRecursiveComparison()
에 관한 내용은 이곳에서 확인하실 수 있습니다.
실행 결과
테스트 통과
Gradle
빌드를 했다면, build에MemberMapperImpl
라는 이름으로 실제코드가 자동으로 구현된것을 확인할 수 있습니다.IntelliJ
빌드를 했다면, out에서 확인하실 수 있습니다.
@Builder
어노테이션을 사용했기 때문에, 빌더를 이용해 구현되는것도 확인할 수 있습니다.
@Builder 를 사용하지 않아도, 사용이 가능합니다.
1 |
|
1 |
|
@Builder
어노테이션을 제거한경우, 생성자에 주입해주며 변환작업을 하는 코드가 만들어지는것을 확인할 수 있습니다.
DTO와 Entity의 형태가 같은 경우
메소드에
@Mapping
어노테이션을 따로 달아주지 않아도 됩니다.
1 |
|
1 |
|
1 |
|
테스트 코드
통과
1 |
|
DTO와 Entity의 필드명이 다른경우
1 |
|
@Mapping
어노테이션의 source와 taget 속성을 이용합니다.
1 |
|
1 |
|
테스트코드
통과
1 |
|
ETC
- Mapping을 지원해주는 라이브러리는 MapStruct 외에도 다양하게 있습니다.
- 하지만 퍼포먼스를 비교한 자료와 점유율을 확인한 자료를 본다면, 저는 MapStruct 를 선택하겠습니다.
- 이 이유 외에도 컴파일단에서 오류가 확인되고, 직접 생성된 코드를 확인할 수 있고, 속도에 영향을 받는 리플랙션을 사용하지 않는다는 점에서 MapStruct을 사용할 이유는 충분해보입니다.
Code
- 해당코드들은 전부 github에서 확인 하실 수 있습니다.
Reference
- https://mapstruct.org/
- https://mapstruct.org/documentation/stable/reference/html/#_gradle
- https://meetup.toast.com/posts/213
- https://www.baeldung.com/java-performance-mapping-frameworks
- https://huisam.tistory.com/entry/mapStruct