티스토리 뷰

내 프로젝트에는 Member, Product, Cart domain이 존재한다

Cart는 Member를 N : 1 & Product를 1 : 1로 가지고 있는 Entity이다

 

 

 

이 상황에서 Cart를 응답하기 위한 CartResponse로 변환하고 GenericMapper를 그대로 쓰면 어떻게 될까? 

당연히 Cart의 속성 member와 product가 그대로 나간다

변화 가능성이 큰 Entity로 응답하지 않기 위해 DTO 형태로 만들어 반환하는 것인데 현재의 DTO는 이를 위반한다

 

 

 

기존의 GenericMapper를 이용하며 member와 product도 dto 형태로 만들어 반환해줘야한다

약간의 커스텀 작업이 필요하다 우선 CartResponse에 Entity가 아닌 DTO 형태를 명시해준다

 

 

 

GenericMapper를 그대로 상속받으면서 Service 계층에서 사용할 메서드

toDto, toEntity, updateFromDto를 오버라이딩 해준다

먼저 스프링 컨테이너가 찾을 수 있도록 @Mapper(componentModel = "spring")을 적어주도록 하고

 

여기서 핵심은 @Mappings 부분이다

매핑할 속성의 이름이 같다면 MapStruct가 알아서 매핑해주지만 이름이 다른 경우 지정해주어야 한다

 

toDto의 경우 member -> memberResponse 형태이므로 source / target을 맞춰주고 toEntity는 반대로 맞춰준다

updateFromDto를 오버라이딩할 때 기본적으로 @BeanMapping과 @MappingTarget이 붙지 않는다 

Test를 돌리면 updateFromDto에서 예외가 발생해 터지기 때문에 

GenericMapper에서 해당 부분을 찾아와 다시 붙여주도록 한다

 

@Mapper(componentModel = "spring")
public interface CartResponseMapper extends GenericMapper<CartResponse, Cart> {

    @Override
    @Mappings({
    	@Mapping(source = "member", target = "memberResponse"), 
	@Mapping(source = "product", target = "productResponse")})
    CartResponse toDto(Cart cart);

    @Override
    @Mappings({
    	@Mapping(source = "memberResponse", target = "member"), 
	@Mapping(source = "productResponse", target = "product")})
    Cart toEntity(CartResponse cartResponse);

    @Override
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    @Mappings({
    	@Mapping(source = "memberResponse", target = "member"), 
	@Mapping(source = "productResponse", target = "product")})
    void updateFromDto(CartResponse dto, @MappingTarget Cart entity);
}

 

 

이렇게 하면 기존 Mapper들과 똑같이 작동하며 원하는 DTO 형태로 반환된다

 

댓글
링크
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday