GrowMe

[Spring] Mapper와 MapStruct에 대해 알아보자 본문

About Spring

[Spring] Mapper와 MapStruct에 대해 알아보자

오늘도 타는중 2022. 6. 28. 18:34
Mapper와 MapStruct
# Mapper
# Mapper 사용법
# 자동생성
# MapStruct

*Mapper란?

  • 클래스 간의 타입을 서로 교체해주는 기술
  • 변환 작업만 따로 빼내어, 본래 기능 구현이나, 관심사에만 보다 집중할 수 있게 해준다.

*Mapper의 사용법

1. Mapper 클래스를 직접 구현하기

- Mapper 클래스 생성

@Component
public class MemberMapper {
		// (2) MemberPostDto를 Member로 변환
    public Member memberPostDtoToMember(MemberPostDto memberPostDto) {
        return new Member(0L,
                memberPostDto.getEmail(), 
                memberPostDto.getName(), 
                memberPostDto.getPhone());
    }

		// (3) MemberPatchDto를 Member로 변환
    public Member memberPatchDtoToMember(MemberPatchDto memberPatchDto) {
        return new Member(memberPatchDto.getMemberId(),
                null, 
                memberPatchDto.getName(), 
                memberPatchDto.getPhone());
    }

    // (4) Member를 MemberResponseDto로 변환
    public MemberResponseDto memberToMemberResponseDto(Member member) {
        return new MemberResponseDto(member.getMemberId(),
                member.getEmail(), 
                member.getName(), 
                member.getPhone());
    }
}
  • @Component를 통해, Mapper를 빈으로 등록한다.
  • 생성자를 활용해, 매개변수에 변환을 시킬 클래스, 반환타입에 변환 결과로 나올 클래스 타입으로 하여
    메소드를 정의한다.
  • 서로 변환을 시킬 클래스는 미리 생성되어져 있어야한다.

- Mapper 클래스를 Controller에 적용

@RestController
@RequestMapping("/v4/members")
@Validated
public class MemberController {
    private final MemberService memberService;
    private final MemberMapper mapper;

		// Mapper 주입
    public MemberController(MemberService memberService, MemberMapper mapper) {
        this.memberService = memberService;
        this.mapper = mapper;
    }

    @PostMapping
    public ResponseEntity postMember(@Valid @RequestBody MemberPostDto memberDto) {
		// 매퍼를 이용해서 MemberPostDto를 Member로 변환
        Member member = mapper.memberPostDtoToMember(memberDto);

        Member response = memberService.createMember(member);

		// 매퍼를 이용해서 Member를 MemberResponseDto로 변환
        return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), 
                HttpStatus.CREATED);
    }

    @PatchMapping("/{member-id}")
    public ResponseEntity patchMember(
            @PathVariable("member-id") @Positive long memberId,
            @Valid @RequestBody MemberPatchDto memberPatchDto) {
        memberPatchDto.setMemberId(memberId);

		// 매퍼를 이용해서 MemberPatchDto를 Member로 변환
        Member response = 
              memberService.updateMember(mapper.memberPatchDtoToMember(memberPatchDto));

        	// 매퍼를 이용해서 Member를 MemberResponseDto로 변환
        return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), 
                HttpStatus.OK);
    }
 }

 

🦴남겨진 문제점

  • Member 외, 도메인이 추가될 때마다 모두 Mapper를 만들어줘야한다.
  • Mapper 클래스를 자동으로 만들어주는 MapStruct를 사용해보자.

2. MapStrut 사용하기

- MapStruct 의존 라이브러리 설정

dependencies {
	...
	...
	implementation 'org.mapstruct:mapstruct:1.4.2.Final'
	annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
  • build.gradle 파일에 위를 추가하면, @Mapper가 붙은 클래스를 보고, MapStruct 기반의 Mapper 클래스를 자동 구현 해준다.

- Mapper 인터페이스 정의

@Mapper(componentModel = "spring")  // (1)
public interface MemberMapper {
    Member memberPostDtoToMember(MemberPostDto memberPostDto);
    Member memberPatchDtoToMember(MemberPatchDto memberPatchDto);
    MemberResponseDto memberToMemberResponseDto(Member member);
  • 인자 : 변환을 시켜주고 싶은 클래스
  • 반환타입 : 변환하여 나올 결과 클래스
  • @Mapper : 이 인터페이스를 MapStruct의 Mapper 인터페이스로 정의하겠다고 명시.
    componentModel 속성 값으로 "spring"을  지정해주면, 이 인터페이스가 Spring의 빈으로 등록된다.

- Mapper 구현 클래스 생성 실행(build)

  • Gradle의 build task를 실행하면 Mapper가 자동 구현된다.

- Mapper 구현 클래스 생성된 위치

  • Project 탭 / 프로젝트명 / build 디렉토리 내의 Mapper 인터페이스가 위치한 경로에 구현 클래스가 생성된다.

  • 구현 클래스가 잘 생성된 것을 확인 할 수 있다.
Comments