Mapstruct 소개 - leegwichan/StackOverFlow_Refactoring GitHub Wiki
- mapper : 한 객체의 정보를 토대로 다른 객체를 만들어주는 것을 담당함
- 주로 Entity -> DTO , DTO -> Entity 변환할 때 사용한다.
- mapper는 코드를 통해 손 쉽게 구현할 수 있다.
- 직접 구현한다면 entity나 DTO의 구조가 변경될 때마다 같이 변경되야 하는 단점이 있다.
- 외부에서 Object-to-object mapping framework를 사용한다면 해당 DTO, Entity 구조를 자동으로 인식해서 사용할 수 있게 된다.
// 직접 구현 @Component public class MemberMapper { public MemberDto toDto(Member member) { return MemberDto.builder() .id(member.getId()) .email(member.getEmail()) .nickname(member.getNickname()) .birthday(member.getBirthday()) .build(); } public List<MemberDto> toDto(List<Member> members) { return members.stream() .map(this::toDto) .collect(Collectors.toList()); } } // Mapstruct 사용 @Mapper(componentModel = "spring") public interface MemberMapper { MemberDto toDto(Member member); List<MemberDto> toDto(List<Member> members); }
- 외부 Object-to-object mapping framework의 종류와 성능 비교
- Mapstruct가 성능이 좋은 이유
- ObjectMapper나 ObjectUtils는 내부에서 맵핑 대상이 되는 클래스에 리플렉션을 사용해서 객체 맵핑을 진행하는데, 퍼포먼스가 떨어지는 기능이다.
- Mapstruct Annotation을 사용하여 컴파일 시 builder, setter를 이용하여 매핑 코드를 생성하기 때문에 퍼포먼스가 좋다.
-
공식 문서에 언급하는 이점
- 리플렉션 대신 일반 메서드 호출을 사용하여 빠른 실행
- 컴파일 타임 유형 안정성
- 서로 매핑되는 개체와 속성만 매핑 할 수 있다.
- 맵퍼 인터페이스에 정의 한 방식으로만 맵핑이 진행 되기 때문이다.
- 다음과 같은 경우 빌드 시 오류 보고서 지우기
- 매핑이 불완전함
- 매핑이 올바르지 않음
-
이외 장점
- 디버깅이 쉽다.
- 생성된 매핑 코드를 눈으로 확인할 수 있다.