BE/Spring
MapStruct with Kotlin
Taylor Kang
2021. 6. 9. 14:39
Mapper ์ ์ : @Mapper
@Mapper(componentModel = "spring")
interface GenreMapper{
@Mappings(
Mapping(source = "genreCodes", target = "code"),
Mapping(source = "engName", target = "enName"),
//Mapping(source = "krName", target = "krName"),
//Mapping(source = "imageUrl", target = "imageUrl"),
//Mapping(source = "topImageUrl", target = "topImageUrl"),
//Mapping(source = "colorBar", target = "colorBar")
)
fun toGenreDTO(genre: Genre): GenreDTO
}
interface
์ ๋งคํ ๋ฉ์๋๋ฅผ ์ ์ํ๊ณorg.mapstruct.Mapper
์ด๋ ธํ ์ด์ ์ถ๊ฐ
- Mapstruct Code Generator ๊ฐ
@Mapper
๊ฐ ๋ถ์ ์ธํฐํ์ด์ค๋ฅผ ์ฐพ์์XXXImpl
ํํ๋ก ๊ตฌํ์ฒด๋ฅผ ์์ฑํจ
- ๊ตฌํ์ฒด ์์ฑ์ source, target์ด ๋๋ ํด๋์ค์ ์์ฑ๋ช
์ ๋น๊ตํ๊ณ ์๋์ผ๋ก ๋งคํ์ฝ๋๋ฅผ ์์ฑ
- 1:1 ๋งคํ์ด ์ํํ๊ฒ ๋๊ธฐ ์ํด์๋ source, target ์ชฝ ํ์ ์ ์ธ์ด ๋์ผํด์ผํจ
- ์์ฑ๋ช
์ด ๋ค๋ฅผ ๊ฒฝ์ฐ
@Mapping
์ด๋ ธํ ์ด์ ์ ํตํด ๋งคํ์ ๋ณด๋ฅผ ์ง์ ์ ์- ์ฌ๋ฌ๊ฐ์ Mapping์ ์ ์ํ ๊ฒฝ์ฐ
@Mappings
์ด๋ ธํ ์ด์ ์ผ๋ก ๋ฌถ์ด์ค์ผํจ
- ์ฌ๋ฌ๊ฐ์ Mapping์ ์ ์ํ ๊ฒฝ์ฐ
- source, target class ์ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ๋ฐ๋์ ์ ์ธ๋์ด์์ด์ผ ํ๋ฉฐ source ์๋ setter๊ฐ, target์๋ getter๊ฐ ํ์ํจ (
data
class ์ฌ์ฉํ๋ฉด ๋จ)
@Mapper(componentModel = "spring")
: Impl ์ ์คํ๋ง์ ์ฑ๊ธํค ๋น์ผ๋ก ๊ด๋ฆฌ๋จ(@Component
)
MapStruct๊ฐ ์์ฑํ ๊ตฌํ์ฒด
build/generated/source/kapt/...
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-05-17T18:09:21+0900",
comments = "version: 1.4.2.Final, compiler: IncrementalProcessingEnvironment from kotlin-annotation-processing-gradle-1.4.30.jar, environment: Java 11.0.10 (JetBrains s.r.o.)"
)
@Component
public class GenreMapperImpl implements GenreMapper {
@Override
public GenreDTO toGenreDTO(Genre genre) {
if ( genre == null ) {
return null;
}
String code = null;
String enName = null;
String krName = null;
String imageUrl = null;
String topImageUrl = null;
String colorBar = null;
code = genre.getGenreCodes();
enName = genre.getEngName();
krName = genre.getKrName();
imageUrl = genre.getImageUrl();
topImageUrl = genre.getTopImageUrl();
colorBar = genre.getColorBar();
GenreDTO genreDTO = new GenreDTO( code, enName, krName, imageUrl, topImageUrl, colorBar );
return genreDTO;
}
}
Mapping method ์์ฑ๋ฒ
- source, target์ ์์ฑ๋ช
์ด ๋ค๋ฅธ๊ฒฝ์ฐ
Mapping(source = "genreCodes", target = "code")
- target์ ํน์ ์์ฑ์ ์ ์ธํ๊ณ ์ถ์ ๊ฒฝ์ฐ
ignore = true
๋ก ๋ฌด์ํ ์์ฑ ์ง์
@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) interface GenreMapper { @Mapping(target = "code", ignore = true) fun toGenreDTO(genre: Genre): GenreDTO }
- ์ผ์นํ์ง ์๋ ํ๋ ๋ฌด์ํ๋๋ก ์ ์ฑ
์ค์
unmappedTargetPolicy = ReportingPolicy.IGNORE
unmappedTargetPolicy = ReportingPolicy.ERROR
- ๋งคํ ์ ํ๊น ๊ฐ์ฒด์ ๋ํ ๋งคํ ์ ์ฑ ์ ์๊ฒฉํ๊ฒ ๊ฐ์ ธ๊ฐ๊ธฐ ์ํด ํ๊น ๊ฐ์ฒด์ ๋งคํ ์ ๋งคํ๋์ง ์์ ์์ฑ์ด ์๋ค๋ฉด ์ปดํ์ผ ์๋ฌ๋ฅผ ๋ฐ์์ํค๋๋ก ์ ์ฑ ์ ์ค์
- conversion ๋ฉ์๋๋ฅผ ์ง์ ์ ์
java
object๋ก ๊ฐ์ธ์ ์ ๋ฌ
@Mapper interface GenreMapper { @Mapping(target = "code", expression = "java(genre.getCustomGenreCode())") fun toGenreDTO(genre: Genre): GenreDTO }
- ๋ค์์ ์ํฐํฐ๋ฅผ ํฉ์น๊ธฐ ์ํด ์ฌ๋ฌ๊ฐ์ source parameter๋ฅผ ์ ๋ฌํ๋ ๊ฒฝ์ฐ
- ๊ฐ ์์ฑ๋ค์ ์ด๋ฆ์ ๋น๊ตํ์ฌ ์๋์ผ๋ก ๋งคํ
- source ์์ฑ๋ช
์ด ๊ฒน์น๋ ๊ฒฝ์ฐ
@Mapping
์ด๋ ธํ ์ด์ ์ผ๋ก ์ด๋ source ์์ฑ์ ๋งคํํ ๊ฒ์ธ์ง ๋ช ์
@Mapper interface GenreArtistMapper { @Mappings( Mapping(source = "artist.id", target = "artist_id"), Mapping(source = "artist.name", target = "artist_name"), Mapping(source = "genre.code", target = "genre_code") ) fun toGenreArtistDTO(artist: Artist, genre: Genre): GenreArtistDTO }
- source ๋ก ์ฃผ์ด์ง ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ์ ์ผ๋ก target์ ์์ฑ์ ๋งคํํ ์ ์์
@Mapper interface GenreMapper{ @Mappings( Mapping(source = "genreCodes", target = "code"), Mapping(source = "engName", target = "enName"), Mapping(source = "number", target = "genreNumber") ) fun toGenreDTO(genre: Genre, number: Int): GenreDTO }
- Mapping method๋ฅผ ์ง์ ๊ตฌํ
- mapstruct๋ก ๋งคํ์ฝ๋๋ฅผ ๊ตฌํํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ
- interface์
default
๋ฉ์๋๋ก ์ปค์คํ ๋งคํ์ ์ถ๊ฐ (kotlin์ ๋ฐ๋ก keyword ๋ถ์ด์ง ์์๋๋จ)- Kotlin
@Mapper interface GenreMapper { fun toGenreDTO(genre: Genre) GenreDTO { // mapping method ์ง์ ๊ตฌํ } }
- Java
@Mapper public interface GenreMapper { default GenreDTO toGenreDTO(Genre genre) { // mapping method ์ง์ ๊ตฌํ } }
๋งํฌ
- https://mapstruct.org/documentation/stable/reference/html/
- https://meetup.toast.com/posts/213
- https://www.tutorialspoint.com/mapstruct/index.htm