MapStruct教程-映射器之间的嵌套调用

开发 前端
我们定义一个Article类和Person类,Person类包含两个简单字段,Article类包含两个简单字段,引用一个Person类字段,然后再定义对应的DTO类。

MapStruct是一个帮助我们在处理Java Bean映射时,尽量减少样板代码的效率工具,只需要定义接口,他会自动生成映射逻辑。之前介绍的目标都是需要映射的对象,本文我们一起看看如何构建复杂的映射器。

一、准备对象

我们定义一个Article类和Person类,Person类包含两个简单字段,Article类包含两个简单字段,引用一个Person类字段,然后再定义对应的DTO类。

为了验证效果,Person类和对应的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;
}

以下是目标类:

@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;
}

基础类准备好了,接下来开始定义映射器。

二、将嵌套映射器定义为方法

让我们从定义一个简单的映射器开始,操作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;
    }
}

这里会自动生成Person到PersonDTO的转换。但是,因为字段名称不对应,无法自动映射,需要我们自己定义字段映射关系。

我们定义一个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);
}

三、定义映射方法

映射器已经定义好了,如何在ArticleMapper中引用PersonMapper呢?有两种方式。

(一)手动编写映射方法

我们可以使用Mappers.getMapper()方法,在ArticleMapper中直接调用PersonMapper的映射方法:

default PersonDTO personToPersonDto(Person person) {
    return Mappers.getMapper(PersonMapper.class).personToPersonDTO(person);
}

MapStruct将自动获取此方法并使用它来映射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;
}

上面这种是纯手动的操作,有些粗糙,我们在看看MapStruct中如何更加优雅一些。

(二)优(zi)雅(dong)的映射

我们可以直接在@Mapper注解中使用uses参数指向我们想要使用的映射器,而不是定义一个新方法:

@Mapper(uses = PersonMapper.class)
public interface ArticleUsingPersonMapper {
    
    ArticleUsingPersonMapper INSTANCE = Mappers.getMapper(ArticleUsingPersonMapper.class);
    
    ArticleDTO articleToArticleDto(Article article);
}

自动生成的映射代码为:

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会自动从PersonMapper中找到映射方法。

是不是很方便,这才是优雅的实现。

责任编辑:武晓燕 来源: 看山的小屋
相关推荐

2022-04-06 09:10:40

映射器代理类接口

2023-01-31 15:17:44

copyMapStruct

2011-09-28 10:17:54

2022-01-25 08:36:29

array.flat映射函数数组

2022-09-02 08:17:40

MapStruct代码工具

2023-10-26 14:34:32

2021-10-14 18:15:38

BeanUtils对象生成器

2024-04-19 08:49:50

微服务RPC事件驱动

2010-01-28 15:22:12

C++嵌套类

2020-12-10 08:21:27

XML映射Mybatis

2010-03-26 15:55:47

Python脚本

2013-05-14 09:28:34

网吧路由器映射端口映射

2024-10-09 12:18:38

2009-06-02 14:46:26

Hibernate关系映射教程

2017-01-23 15:06:32

戴尔服务器

2013-06-07 17:25:46

路由技术路由器

2009-12-02 18:51:11

2022-09-02 15:11:18

开发工具

2020-08-10 10:40:03

工具类MapStructJava

2011-06-08 14:55:37

Qt 教程
点赞
收藏

51CTO技术栈公众号