Mapstruct 소개 - leegwichan/StackOverFlow_Refactoring GitHub Wiki

◎ Mapper

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

◎ Mapstruct

  • 외부 Object-to-object mapping framework의 종류와 성능 비교
  • Mapstruct가 성능이 좋은 이유
    • ObjectMapper나 ObjectUtils는 내부에서 맵핑 대상이 되는 클래스에 리플렉션을 사용해서 객체 맵핑을 진행하는데, 퍼포먼스가 떨어지는 기능이다.
    • Mapstruct Annotation을 사용하여 컴파일 시 builder, setter를 이용하여 매핑 코드를 생성하기 때문에 퍼포먼스가 좋다.

◎ Mapstruct의 장점

  • 공식 문서에 언급하는 이점

    • 리플렉션 대신 일반 메서드 호출을 사용하여 빠른 실행
    • 컴파일 타임 유형 안정성
      • 서로 매핑되는 개체와 속성만 매핑 할 수 있다.
      • 맵퍼 인터페이스에 정의 한 방식으로만 맵핑이 진행 되기 때문이다.
    • 다음과 같은 경우 빌드 시 오류 보고서 지우기
      • 매핑이 불완전함
      • 매핑이 올바르지 않음
  • 이외 장점

    • 디버깅이 쉽다.
    • 생성된 매핑 코드를 눈으로 확인할 수 있다.
⚠️ **GitHub.com Fallback** ⚠️