MapStruct教程-映射器之間的嵌套調(diào)用
MapStruct是一個(gè)幫助我們在處理Java Bean映射時(shí),盡量減少樣板代碼的效率工具,只需要定義接口,他會(huì)自動(dòng)生成映射邏輯。之前介紹的目標(biāo)都是需要映射的對象,本文我們一起看看如何構(gòu)建復(fù)雜的映射器。
一、準(zhǔn)備對象
我們定義一個(gè)Article類和Person類,Person類包含兩個(gè)簡單字段,Article類包含兩個(gè)簡單字段,引用一個(gè)Person類字段,然后再定義對應(yīng)的DTO類。
為了驗(yàn)證效果,Person類和對應(yīng)的DTO類字段名不同。
以下是源類:
@Getter
@Setter
public class Article {
    private int id;
    private String name;
    private Person author;
}
@Getter
@Setter
public class Person {
    private String id;
    private String name;
}以下是目標(biāo)類:
@Getter
@Setter
public class ArticleDTO {
    private int id;
    private String name;
    private PersonDTO author;
}
@Getter
@Setter
public class PersonDTO {
    private String personId;
    private String personName;
}基礎(chǔ)類準(zhǔn)備好了,接下來開始定義映射器。
二、將嵌套映射器定義為方法
讓我們從定義一個(gè)簡單的映射器開始,操作Article類:
@Mapper
public interface ArticleMapper {
    ArticleMapper INSTANCE = Mappers.getMapper(ArticleMapper.class);
    ArticleDTO articleToArticleDto(Article article);
}我們看下生成的映射代碼:
public class ArticleMapperImpl implements ArticleMapper {
    @Override
    public ArticleDTO articleToArticleDto(Article article) {
        if ( article == null ) {
            return null;
        }
        ArticleDTO articleDTO = new ArticleDTO();
        articleDTO.setId( article.getId() );
        articleDTO.setName( article.getName() );
        articleDTO.setAuthor( personToPersonDTO( article.getAuthor() ) );
        return articleDTO;
    }
    protected PersonDTO personToPersonDTO(Person person) {
        if ( person == null ) {
            return null;
        }
        PersonDTO personDTO = new PersonDTO();
        return personDTO;
    }
}這里會(huì)自動(dòng)生成Person到PersonDTO的轉(zhuǎn)換。但是,因?yàn)樽侄蚊Q不對應(yīng),無法自動(dòng)映射,需要我們自己定義字段映射關(guān)系。
我們定義一個(gè)PersonMapper映射器:
@Mapper
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
    @Mapping(source = "id", target = "personId")
    @Mapping(source = "name", target = "personName")
    PersonDTO personToPersonDTO(Person person);
}三、定義映射方法
映射器已經(jīng)定義好了,如何在ArticleMapper中引用PersonMapper呢?有兩種方式。
(一)手動(dòng)編寫映射方法
我們可以使用Mappers.getMapper()方法,在ArticleMapper中直接調(diào)用PersonMapper的映射方法:
default PersonDTO personToPersonDto(Person person) {
    return Mappers.getMapper(PersonMapper.class).personToPersonDTO(person);
}MapStruct將自動(dòng)獲取此方法并使用它來映射author字段,生成的代碼為:
@Override
public ArticleDTO articleToArticleDto(Article article) {
    if ( article == null ) {
        return null;
    }
    ArticleDTO articleDTO = new ArticleDTO();
    articleDTO.setId( article.getId() );
    articleDTO.setName( article.getName() );
    articleDTO.setAuthor( personToPersonDto( article.getAuthor() ) );
    return articleDTO;
}上面這種是純手動(dòng)的操作,有些粗糙,我們在看看MapStruct中如何更加優(yōu)雅一些。
(二)優(yōu)(zi)雅(dong)的映射
我們可以直接在@Mapper注解中使用uses參數(shù)指向我們想要使用的映射器,而不是定義一個(gè)新方法:
@Mapper(uses = PersonMapper.class)
public interface ArticleUsingPersonMapper {
    
    ArticleUsingPersonMapper INSTANCE = Mappers.getMapper(ArticleUsingPersonMapper.class);
    
    ArticleDTO articleToArticleDto(Article article);
}自動(dòng)生成的映射代碼為:
public class ArticleUsingPersonMapperImpl implements ArticleUsingPersonMapper {
    private final PersonMapper personMapper = PersonMapper.INSTANCE;
    @Override
    public ArticleDTO articleToArticleDto(Article article) {
        if ( article == null ) {
            return null;
        }
        ArticleDTO articleDTO = new ArticleDTO();
        articleDTO.setId( article.getId() );
        articleDTO.setName( article.getName() );
        articleDTO.setAuthor( personMapper.personToPersonDTO( article.getAuthor() ) );
        return articleDTO;
    }
}從生成的映射代碼看到,雖然沒有指定author字段的映射,但是MapStruct會(huì)自動(dòng)從PersonMapper中找到映射方法。
是不是很方便,這才是優(yōu)雅的實(shí)現(xiàn)。
















 
 
 











 
 
 
 