Mapper
1
2
3
4
5
6
7
8
@Component // (1)
public class MemberMapper {
// (2) MemberPostDto를 Member로 변환
public Member memberPostDtoToMember(MemberPostDto memberPostDto) {
return new Member(0L,
memberPostDto.getEmail(),
memberPostDto.getName(),
❓Mapper란
데이터 변환, 매핑 또는 연결을 수행하는 데 사용됨
매퍼를 이용해서 Dto클래스와 Entity 연결
MapStruct를 이용한 Mapper 자동 생성
매퍼(Mapper) 클래스를 사용하면 DTO 클래스와 엔티티(Entity) 클래스의 변환 작업을 깔끔하게 처리할 수있음
각각의 핸들러 메서드를 처리하는 DTO 클래스에 해당하는 매퍼(Mapper) 클래스를 추가적으로 만들어야 함
개발자가 일일이 수작업으로 매퍼(Mapper) 클래스를 만드는 것은 비효율적임
이때 MapStruct가 매퍼 클래스를 자동으로 구현해 줌으로써 개발자의 생산성을 향상해줄 수 있습니다.
MapStruct는 DTO 클래스처럼 Java Bean 규약을 지키는
객체들 간의 변환 기능을 제공하는 매퍼(Mapper) 구현 클래스를 자동으로 생성해 주는 코드 자동 생성기
의존성 추가
1
2
3
4
5
6
dependencies {
...
...
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
DTO 클래스를 변환하는 매퍼(Mapper)를 자동으로 생성하기 위해서는
매퍼(Mapper) 인터페이스를 먼저 정의해야 함
1
2
3
4
5
6
7
8
9
10
11
12
import com.codestates.member.dto.MemberPatchDto;
import com.codestates.member.dto.MemberPostDto;
import com.codestates.member.dto.MemberResponseDto;
import com.codestates.member.entity.Member;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring") // (1)
public interface MemberMapper {
Member memberPostDtoToMember(MemberPostDto memberPostDto);
Member memberPatchDtoToMember(MemberPatchDto memberPatchDto);
MemberResponseDto memberToMemberResponseDto(Member member);
}
MemberMapper 인터페이스에 정의한 메서드가 직접 수작업으로 작성한 MemberMapper 클래스를 대체 해줌
@Mapper 애너테이션을 추가함으로써 인터페이스는 MapStruct의 매퍼 인터페이스로 정의
@Mapper애너테이션의 애트리뷰트로 componentModel = “spring”을 지정해 주면Spring의 Bean으로 등록이 됨
MapStruct가 MemberMapper 인터페이스를 기반으로 매퍼(Mapper) 구현 클래스를 자동으로 생성해 줌
Mapper를 사용해서
DTO 클래스와 엔티티 클래스의 역할 분리가 필요한 이유
✔ 계층별 관심사의 분리
우선 서로 사용되는 계층이 다름 따라서 기능에 대한 관심사가 다름
DTO 클래스는 API 계층에서 요청 데이터를 전달받고, 응답 데이터를 전송하는 것이 주 목적인
반면에 Entity 클래스는 서비스 계층에서 데이터 액세스 계층과 연동하여
비즈니스 로직의 결과로 생성된 데이터를 다루는 것이 주목적임
✔ 코드 구성의 단순화
DTO 클래스에서 사용하는 유효성 검사 애너테이션이 Entity 클래스에서 사용이 된다면
JPA에서 사용하는 애너테이션과 뒤섞인 상태가 되어 유지보수하기 상당히 어려운 코드가 됨
✔ REST API 스펙의 독립성 확보
데이터 액세스 계층에서 전달받은 데이터로 채워진 Entity 클래스를
클라이언트의 응답으로 그대로 전달하게 되면 원치 않는 데이터까지 클라이언트에게 전송될 수 있음
대표적인 예가 바로 회원의 로그인 패스워드임
DTO 클래스를 사용하면 회원의 로그인 패스워드 같은 정보를 클라이언트에게 노출하지 않고,
원하는 정보만 제공할 수 있음