MapStruct
Overview
This article creates a project that uses MapStruct to copy values between classes.
The official MapStruct site is as follows.
Configuration
Add kapt to the build script’s plugins section as shown below.
/build.gradle.kts
plugins {
kotlin("jvm") version "1.7.10"
kotlin("kapt") version "1.5.10"
}
Add the related libraries and kapt to dependencies.
/build.gradle.kts
dependencies {
testImplementation(kotlin("test"))
implementation("org.mapstruct:mapstruct:1.5.2.Final")
kapt("org.mapstruct:mapstruct-processor:1.5.2.Final")
}
Creating Data Classes
First, create the User domain class.
/src/main/kotlin/com/devkuma/mapstruct/domain/User.kt
package com.devkuma.mapstruct.domain
data class User(
val name: String,
val age: Int,
val city: String?
)
Then create the UserDto class.
/src/main/kotlin/com/devkuma/mapstruct/domain/UserDto.kt
package com.devkuma.mapstruct.dto
data class UserDto(
val name: String,
val age: Int,
val city: String?
)
Creating the Mapper Class
Create the mapper class. /src/main/kotlin/com/devkuma/mapstruct/mapper/UserDto.kt
package com.devkuma.mapstruct.mapper
import com.devkuma.mapstruct.dto.UserDto
import com.devkuma.mapstruct.domain.User
import org.mapstruct.Mapper
import org.mapstruct.factory.Mappers
@Mapper
interface UserMapper {
fun convertToDto(s: User): UserDto
fun convertToDomain(s: UserDto): User
companion object {
val INSTANCE: UserMapper = Mappers.getMapper(UserMapper::class.java)
}
}
Creating Converter Functions in the Data Classes
Create the DTO converter function convertToDto() in the User domain class.
/src/main/kotlin/com/devkuma/mapstruct/domain/User.kt
package com.devkuma.mapstruct.domain
import com.devkuma.mapstruct.mapper.UserMapper
class User(
val name: String,
val age: Int,
val city: String?
) {
fun convertToDto() = UserMapper.INSTANCE.convertToDto(this)
}
Create the domain converter function convertToDomain() in the UserDto class.
/src/main/kotlin/com/devkuma/mapstruct/dto/UserDto.kt
package com.devkuma.mapstruct.dto
import com.devkuma.mapstruct.mapper.UserMapper
class UserDto(
val name: String,
val age: Int,
val city: String?
) {
fun convertToDomain() = UserMapper.INSTANCE.convertToDomain(this)
}
Creating Test Code
Create convertToDto() for the User domain class.
package com.devkuma.mapstruct.domain
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertAll
import kotlin.test.assertEquals
class UserTest {
@Test
fun convertToDto(){
// Given
var user = User(
name = "devkuma",
age = 20,
city = "Seoul"
)
// When
var userDto = user.convertToDto()
// Then
assertAll(
{ assertEquals(user.name, userDto.name) },
{ assertEquals(user.age, userDto.age) },
{ assertEquals(user.city, userDto.city) },
)
}
}
Create convertToDomain() for the UserDto class.
package com.devkuma.mapstruct.dto
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertAll
import kotlin.test.assertEquals
class UserDtoTest {
@Test
fun convertToDto(){
// Given
var userDto = UserDto(
name = "devkuma",
age = 20,
city = "Seoul"
)
// When
var user = userDto.convertToDomain()
// Then
assertAll(
{ assertEquals(userDto.name, user.name) },
{ assertEquals(userDto.age, user.age) },
{ assertEquals(userDto.city, user.city) },
)
}
}
Run both test classes and confirm that they do not fail.