-
Kotlin MapStruct 사용하기프로젝트/선착순 쿠폰 발급 시스템 2023. 5. 21. 00:01728x90
MapStruct란?
컴파일 시 매핑 코드를 생성하며 Java Bean 간의 매핑을 단순화하는 Java 기반 코드 생성도구입니다.
MapStruct를 사용하면 객체 간 데이터 매핑을 위해 boilerplate code를 작성할 필요가 없어집니다.
ModelMapper와의 차이점
reflection을 사용하여 객체 간의 필드를 매핑하는 Java 기반 코드 생성도구입니다.
컴파일 시 매핑 코드를 생성하지 않으며, reflection을 사용하기 때문에 MapStruct보다 속도가 느릴 수 있습니다.
Kotlin DSL Gradle MapStruct 적용
plugins { kotlin("kapt") version "1.7.10" } subprojects { apply(plugin = "kotlin-kapt") dependencies { implementation("org.mapstruct:mapstruct:1.5.2.Final") kapt("org.mapstruct:mapstruct-processor:1.5.2.Final") kaptTest("org.mapstruct:mapstruct-processor:1.5.2.Final") } }
MapStruct 사용법
person class와 personDto class가 존재한다고 가정해 보겠습니다.
data class Person( var firstName: String?, var lastName: String?, var phoneNumber: String?, var birthdate: LocalDate? )
data class PersonDto( var firstName: String?, var lastName: String?, var phone: String?, var birthdate: LocalDate? )
person model을 personDto로 변환하는 경우 PersonMapper를 다음과 같이 정의하면 됩니다.
@Mapper interface PersonMapper { @Mapping(source = "phoneNumber", target = "phone") fun convertToDto(person: Person) : PersonDto @InheritInverseConfiguration fun convertToModel(personDto: PersonDto) : Person }
phoneNumber, phone과 같이 이름이 다를 경우는 Mapping 어노테이션을 이용해서 정의해주어야 합니다.
@InheritInverseConfiguration 어노테이션은 person -> PersonDto의 역방향인 personDto -> person 매핑 코드를 생성하도록 해줍니다.
Converting 하는 방법
val converter = Mappers.getMapper(PersonMapper::class.java) val person = Person("Samuel", "Jackson", "0123 334466", LocalDate.of(1948, 12, 21)) val personDto = converter.convertToDto(person) println(personDto) val personModel = converter.convertToModel(personDto) println(personModel)
PersonMapper Interface로부터 converter를 만들어준 후 해당 메서드를 호출해 주면 변환이 자동으로 수행됩니다.
동작 원리
public class CarMapperImpl implements CarMapper { @Override public CarDto carToCarDto(Car car) { if ( car == null ) { return null; } CarDto carDto = new CarDto(); if ( car.getFeatures() != null ) { carDto.setFeatures( new ArrayList<String>( car.getFeatures() ) ); } carDto.setManufacturer( car.getMake() ); carDto.setSeatCount( car.getNumberOfSeats() ); carDto.setDriver( personToPersonDto( car.getDriver() ) ); carDto.setPrice( String.valueOf( car.getPrice() ) ); if ( car.getCategory() != null ) { carDto.setCategory( car.getCategory().toString() ); } carDto.setEngine( engineToEngineDto( car.getEngine() ) ); return carDto; } @Override public PersonDto personToPersonDto(Person person) { //... } private EngineDto engineToEngineDto(Engine engine) { if ( engine == null ) { return null; } EngineDto engineDto = new EngineDto(); engineDto.setHorsePower(engine.getHorsePower()); engineDto.setFuel(engine.getFuel()); return engineDto; } }
MapStruct의 일반적인 철학은 가능한 한 직접 작성한 것처럼 보이는 코드를 생성하는 것입니다.
특히 이것은 값이 소스에서 복사된다는 것을 의미합니다.
일반 게터/세터 호출을 통해 타깃으로 값을 복사합니다.
생성된 코드는 @Mapping을 통해 지정된 모든 이름 매핑을 고려합니다.매핑된 속성의 유형이 소스 엔티티와 대상 엔티티에서 다른 경우, MapStruct는 자동 변환을 적용하거나 선택적으로 다른 매핑 메서드를 호출/생성합니다
참고자료
https://github.com/mapstruct/mapstruct-examples/tree/main/mapstruct-kotlin
https://mapstruct.org/documentation/stable/reference/pdf/mapstruct-reference-guide.pdf
'프로젝트 > 선착순 쿠폰 발급 시스템' 카테고리의 다른 글
Kotlin JPA 양방향 연관관계 매핑 (0) 2023.05.25 Kotlin Jpa Auditing - Entity 수정, 생성기간 저장 (0) 2023.05.24 Spring Data Redis TTL설정하기 (0) 2023.05.20 OpenAPI Specification으로 API-First 개발하기 (0) 2023.05.18 쿠폰 발급을 위한 Redis Set Document 읽기 (0) 2023.05.06