아무거나

객체 간 매핑을 위한 Kotlin MapStruct 적용 본문

Java & Kotlin/Kotlin

객체 간 매핑을 위한 Kotlin MapStruct 적용

전봉근 2024. 6. 28. 17:59
반응형

MapStruct 적용

[설명]

  • 컴파일 시 매핑 코드를 생성하며 Java Bean 간의 매핑을 단순화하는 Java 기반 코드 생성도구입니다. MapStruct를 사용하면 객체 간 데이터 매핑을 위해 boilerplate code를 작성할 필요가 없어진다.
  • MapStruct 에 사용될 Data Class 의 Property 는 var 로 생성해야 한다. 왜냐하면 MapStruct 가 Getter / Setter로 내부 구현체를 생성해서, val 로 선언할 경우 불변이기 때문에 Set 을 할 수 없다.

[특징]

  • 컴파일 시점에 코드를 생성하여 런타임에서 안정성을 보장
  • 다른 매핑 라이브러리보다 속도가 빠름
  • 반복되는 객체 매핑에서 발생할 수 있는 오류를 줄일 수 있으며, 구현 코드를 자동으로 만들어주기 때문에 사용이 쉬움
  • Annotation processor를 이용하여 객체 간 매핑을 자동으로 제공

단, Lombok 라이브러리에 먼저 Dependency (의존성) 추가가 되어있어야 합니다. MapStruct는 Lombok의 @Getter, @Setter, @Builder를 이용하여 생성되므로 Lombok 보다 먼저 의존성이 선언된 경우 실행할 수 없다. (코틀린은 Lombok 을 사용하지 않고 구현할 수 있다.)

  1. 의존성 추가(build.gradle.kts)
...

plugins {
	...

	// MapStruct
	kotlin("kapt") version "1.7.10"
}

...
	
apply(plugin = "kotlin-kapt")
implementation("org.mapstruct:mapstruct:1.5.5.Final")
kapt("org.mapstruct:mapstruct-processor:1.5.5.Final")
kaptTest("org.mapstruct:mapstruct-processor:1.5.5.Final")

...
  1. 요청 DTO 생성
    [EsRequest.kt]
data class EsRequest(
    var title: String?,
    var author: String?,
    var age: Int?,
    var ageNosStr: String?,
    var startDate: String?,
    var endDate: String?
)
  1. 서비스 DTO 생성 [EsBkjeonIndexDto.kt]
data class EsBkjeonIndexDto(
    var esStartDate: String? = null,
    var esEndDate: String? = null,
    var title: String? = null,
    var content: String? = null,
    var author: String? = null,
    var age: Int? = null,
    var date: String? = null,
    var tags: List<String>? = null,
    var ageNoList: List<String>? = null,
    var constTest: String? = null,
)
  1. Converter 생성 [EsRequestConverter.kt]
import com.bkjeon.base.feature.dto.elasticsearch.EsBkjeonIndexDto
import com.bkjeon.base.v1.api.elasticsearch.model.EsRequest
import org.mapstruct.Mapper

@Mapper
interface EsRequestConverter {

    @Mappings(
        Mapping(source = "startDate", target = "esStartDate"),
        Mapping(source = "endDate", target = "esEndDate"),
        Mapping(target = "constTest", constant = CommonConst.YES)   // CommonConst.YES 는 "Y" 입니다.
    )
    fun convertToEsBkjeonIndexDto(request: EsRequest): EsBkjeonIndexDto

}
  1. 서비스에 추가 [ElasticsearchService.kt]
...

@Service
class ElasticsearchService(
    val esSampleRepository: ElasticsearchSampleRepository
) {
    companion object {
        val converter: EsRequestConverter = Mappers.getMapper(EsRequestConverter::class.java)
    }

    fun getSampleTotalCnt(request: EsRequest): Long {
        // MapStruct Converter 호출
        return esSampleRepository.getTotalCnt(converter.convertToEsBkjeonIndexDto(request))
    }    
}

 

 

참고

https://medium.com/naver-cloud-platform

 

NAVER CLOUD PLATFORM – Medium

네이버 클라우드 플랫폼 기술 블로그 입니다.

medium.com

https://junuuu.tistory.com/

반응형
Comments