Spring

Mappstruct 사용

쭈녁 2024. 3. 11. 01:45

 

Mappstruct를 적용하여 사용하여 보았다.

여러 Entity와 DTO 계층의 자동 매핑을 위해 모든 Entity를 대상으로 하는 인터페이스를 두었다

 

build.gradle

//mapstruct
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'

 

EntityMapper

public interface EntityMapper<D, E>{ //제네릭 타입으로 DTO와 Entity를 받는다.
    //단일 Entity -> result
    D toDto(final E entity);
    //list 형식 Entity -> result
    List<D> toDtoList(final List<E> entities);
    }
}

 

Entity

@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Entity
public class Item extends BassEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private SecondCategory secondCategory;

    private String name;

    private Integer price;

    private Integer stock;

    private String content;

    private Integer sellCount;

    private Integer discountPer;
}

 

DTO 계층

@Getter
@Setter
public class ItemResult {
    private Long id;

    private String name;

    private String content;

    private Integer price;

    private Integer discountPer;

}

 

ItemResultMapper

이를 상속받은 구체 매핑 인터페이스를 만든다.

@Mapper(componentModel = "spring")
public interface ItemResultMapper extends EntityMapper<ItemResult, Item> {
}

 

ItemResultMapperImpl

빌드 시점에 generated 하위 동일한 경로에 Entity와 Dto의 프로퍼티를 기반으로 구현체가 생성된다.

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2024-03-10T23:54:58+0900",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 21.0.1 (Oracle Corporation)"
)
@Component
public class ItemResultMapperImpl implements ItemResultMapper {

    @Override
    public ItemResult toDto(Item entity) {
        if ( entity == null ) {
            return null;
        }

        ItemResult itemResult = new ItemResult();

        itemResult.setId( entity.getId() );
        itemResult.setName( entity.getName() );
        itemResult.setContent( entity.getContent() );
        itemResult.setPrice( entity.getPrice() );
        itemResult.setDiscountPer( entity.getDiscountPer() );

        return itemResult;
    }

    @Override
    public List<ItemResult> toDtoList(List<Item> entities) {
        if ( entities == null ) {
            return null;
        }

        List<ItemResult> list = new ArrayList<ItemResult>( entities.size() );
        for ( Item item : entities ) {
            list.add( toDto( item ) );
        }

        return list;
    }
}

 

서비스 계층 사용 예

@Service
@RequiredArgsConstructor
public class ItemServiceImpl {
    private final ItemResultMapper itemResultMapper;

    public ItemResult findItem(Long id) {
        Item item = itemRepository.findById(id).orElseThrow());
        ItemResult dto = itemResultMapper.toDto(item);
        return dto;
    }
}

 

주의점

자동으로 구현된 Mapstruct 객체는 setter와 getter를 동일한 프로퍼티명으로 호출한다.

따라서 자동 매핑을 설정할 때 Entity와 DTO 계층의 프로퍼티 이름을 동일하게 설정하여야 한다.

 

 

'Spring' 카테고리의 다른 글

Security CORS 설정  (0) 2024.03.17
Security 인가(Authorization) 적용  (1) 2024.03.16
SpringSecurity 프로젝트 적용  (0) 2024.03.03
SpringSecurity 인증 방식  (0) 2024.03.02
SpringSecurity 인증  (0) 2024.03.01