美文网首页
如何优雅的转换对象

如何优雅的转换对象

作者: bailiyi | 来源:发表于2020-01-20 19:56 被阅读0次

什么是样板代码

样板代码就是那些和主要逻辑无关,却又不得不写的代码.
比如一段常见的实体类映射代码:

    public User toUser(UserAddr addr, UserInfo info) {
        User user = new User();
        user.setAddr( addr.getAddress() );
        user.setCountry( addr.getCountry() );
        user.setCity( addr.getCity() );
        user.setName( info.getNameCn() );
        user.setAge( info.getAge() );
        return user;
    }

我们想把某个对象的属性赋值给另一个对象时,不可避免的要写上一大堆get/set之类的操作.
就算使用BeanUtils.copyProperties()方法,也只能消除同名属性的get/set操作.
那有没有一种方法,可以完全消除这种样板代码呢?
有的.

使用mapstruct的效果

先不说怎么用,咱们先看看效果,觉得有用,咱们再往下看.
首先,写一个映射接口

@Mapper(componentModel = "spring")
public interface UserDOMapper {
    @Mapping(source = "info.nameCn",target = "name")
    @Mapping(source = "addr.address",target = "addr")
    User toUser(UserAddr addr, UserInfo info);
}

然后就可以使用了

@Autowired
private UserDOMapper userDOMapper;
public User toUser(UserAddr addr, UserInfo info) {
    return userDOMapper.toUser(addr,info);
}
    

修改前后的toUser作用完全相同,这效果可还行?

mapstruct的简单使用

引入依赖

<properties>
        <org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
</properties>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>${org.mapstruct.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${org.mapstruct.version}</version>
</dependency>

编写映射器:产生新对象

@Mapper(componentModel = "spring")
public interface UserDOMapper {
    @Mapping(source = "info.nameCn",target = "name")
    @Mapping(source = "addr.address",target = "addr")
    User toUser(UserAddr addr, UserInfo info);
}

如果是要产生新对象,可以按照如上写法编写映射器.
source表示数据来源,target表示要赋值的变量.
比如@Mapping(source = "addr.address",target = "addr")就表示,把入参addr的address变量的值,赋值给User中的addr变量.
看下UserAddr和User定义会更清楚些:

public class UserAddr {
    private String country;
    private String city;
    private String address;
    ...
}
public class User {
    private String name;
    private Integer age;
    private String country;
    private String city;
    private String addr;
    ...
}

如果是变量的名字和数据类型都相同,则不需要显示的声明映射关系,默认会给复制.

编写映射器:给对象填充值

如果是要给已存在的对象填充值,可以按照下面这样写:

    @Mapping(source = "addr.address",target = "addr")
    void fillUser(UserAddr addr,@MappingTarget User user);

@MappingTarget表示被填充的对象.
其他规则还是跟之前一样

原理

看完了使用,咱们来看下mapstruct是怎么做到这些事的.
实际上,mapstruct是一个代码生成器,在编译项目的时候,它会为映射器生成实现类.
比如下面这个映射器:

@Mapper(componentModel = "spring")
public interface UserDOMapper {
    @Mapping(source = "info.nameCn",target = "name")
    @Mapping(source = "addr.address",target = "addr")
    User toUser(UserAddr addr, UserInfo info);
}

在编译之后,会在target中生成如下实现类:

@Component
public class UserDOMapperImpl implements UserDOMapper {

    @Override
    public User toUser(UserAddr addr, UserInfo info) {
        if ( addr == null && info == null ) {
            return null;
        }

        User user = new User();

        if ( addr != null ) {
            user.setAddr( addr.getAddress() );
            user.setCountry( addr.getCountry() );
            user.setCity( addr.getCity() );
        }
        if ( info != null ) {
            user.setName( info.getNameCn() );
            user.setAge( info.getAge() );
        }

        return user;
    }
}

总结

本次向大家介绍了一种减少样板代码,提高开发效率的工具mapstruct
其本质是一个代码生成器
相比使用反射的BeanUtils.copyProperties()而言,mapstruct的效率更高,代码可追溯性也更好.
推荐大家使用.
更多用法请见官方文档,十分详细且易读
https://mapstruct.org/documentation/reference-guide/

系列文章总目录:https://mp.weixin.qq.com/s/56JgXLArTAEDj1f3y4arLA

相关文章

  • 如何优雅的转换Bean对象?

    背景 我们的故事要从一个风和日丽的下午开始说起! 这天,外包韩在位置上写代码~外包韩根据如下定义 PO(persi...

  • 如何优雅的转换对象

    什么是样板代码 样板代码就是那些和主要逻辑无关,却又不得不写的代码.比如一段常见的实体类映射代码: 我们想把某个对...

  • Opencsv将csv文件转成Bean

    Maven依赖 CsvToBeanBuilder 优雅的解析文档中的字段。将CSV文件转换为Bean对象。 ope...

  • 设计模式

    创建 注:面向对象,首先你得有个对象。如何高效优雅的创建对象呢 简单工厂模式(Simple Factory Pat...

  • 对Javascript 类数组对象的理解与应用 | Argume

    这篇文章将要告诉你: 什么是类数组对象 类数组对象是如何出现的 如何避免使用类数组对象的常见问题 将类数组对象转换...

  • 使用JavaScript将对象转换为字符串

    JavaScript如何将对象转换为字符串?下面本篇文章就来给大家介绍一下使用JavaScript将不同对象转换为...

  • js和jquery对象转换

    js对象转换为jquery对象 jquery对象转换为js对象

  • golang+rgb2hex

    给定一个颜色的rgb值如何转换成hex,反过来又如何转换? 在本节,我们需要掌握基本的面向对象知识--如何给一个类...

  • PHP中的数据转换、类型约束

    数据转换 转换基本语法:(目标类型)数据; 对象转换为对象:没有变化 数组转换为对象:数组的键名当作属性名,值为对...

  • Gradle系列六之Json操作

    将实体对象转换成Json字符串 打印输出为: 更优雅地显示Json字符串,可以调用JsonOutput.prett...

网友评论

      本文标题:如何优雅的转换对象

      本文链接:https://www.haomeiwen.com/subject/hwfszctx.html