这四种对象属性拷贝方式,你都知道吗?

这四种对象属性拷贝方式,你都知道吗?(推荐第四种)


一、MapStruct

1.1、 简介:

MapStruct 是一个自动生成 bean 映射类的代码生成器。MapStruct 还能够在不同的数据类型之间进行转换。

1.2、所需依赖

  • mapstruct-jdk8

包含所需的注释,例如@Mapping。

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
</dependency>


  • mapstruct-processor

在编译,生成映射器实现的注释处理器。

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.3.0.Final</version>
    <scope>provided</scope>
</dependency>

1.3、如何使用?

您所要做的就是定义一个mapper接口,该接口声明任何所需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用普通的Java方法调用来在源对象和目标对象之间进行映射。

  • 创建Mapper

利用@Mapper注解标注该接口/抽象类是被MapStruct自动映射的,只有存在该注解才会将内部的接口方法自动实现。

  • 获取Mapper

MapStruct为我们提供了多种的获取Mapper的方式,习惯用默认配置:采用Mappers通过动态工厂内部反射机制完成Mapper实现类的获取。

UserConvertUtils INSTANCE = Mappers.getMapper(UserConvertUtils.class);

完整的一个转换器demo:

@Mapper
public interface UserConvertUtils {

    UserConvertUtils INSTANCE = Mappers.getMapper(UserConvertUtils.class);

    /**
     * 普通的映射
     *
     * @param userDO UserDO数据持久层类
     * @return 数据传输类
     */
    UserDTO doToDTO(UserDO userDO);

    /**
     * 类型转换的映射
     *
     * @param userDO UserDO数据持久层类
     * @return 数据传输类
     */
    @Mappings({
            @Mapping(target = "gmtBroth", source = "gmtBroth", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "balances", source = "balance"),
    })
    UserDTO doToDtoWithConvert(UserDO userDO);
}
  • 测试
/**
 * 一般拷贝
 */
@Test
public void normalCopy() {
    // 模拟查询出数据
    UserDO userDO = DataUtil.createData();
    log.info("拷贝前:userDO:{}", userDO);
    UserDTO userDTO = UserConvertUtils.INSTANCE.doToDTO(userDO);
    log.info("拷贝后:userDTO:{}", userDTO);
}
/**
 * 包含类型转换的拷贝
 */
@Test
public void doToDtoWithConvert() {
    // 模拟查询出数据
    UserDO userDO = DataUtil.createData();
    log.info("拷贝前:userDO:{}", userDO);
    UserDTO userDTO = UserConvertUtils.INSTANCE.doToDtoWithConvert(userDO);
    log.info("拷贝后:userDTO:{}", userDTO);
}
  • 打印映射结果
一般拷贝:
...拷贝前:userDO:UserDO(id=1, userName=Van, gmtBroth=2020-04-21T21:38:39.376, balance=100)
...拷贝后:userDTO:UserDTO(id=1, userName=Van, gmtBroth=2020-04-21T21:38:39.376, balances=null)
包含类型转换的拷贝:
...拷贝前:userDO:UserDO(id=1, userName=Van, gmtBroth=2020-04-21T21:05:19.282, balance=100)
...拷贝后:userDTO:UserDTO(id=1, userName=Van, gmtBroth=2020-04-21 21:05:19, balances=100)

通过打印结果可以发现:相较于前者,包含类型转换的拷贝可以自定义转换属性和时间格式等。


1.4、MapStruct 注解的关键词

  1. @Mapper:只有在接口加上这个注解, MapStruct 才会去实现该接口;
  2. @Mappings:配置多个@Mapping;
  3. @Mapping:属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性:
  • source:源属性;
  • target:目标属性;
  • dateFormat:字符串与日期之间相互转换;
  • ignore:忽略这个,某个属性不想映射,可以加个 ignore=true;


1.5、多对一

与手工编写映射代码相比,MapStruct通过生成繁琐且易于编写的代码来节省时间。遵循约定优于配置方法,MapStruct使用合理的默认值,但在配置或实现特殊行为时会采取措施。
与动态映射框架相比,MapStruct具有以下优势:

  1. 通过使用普通方法调用而不是反射来快速执行
  2. 编译时类型安全:只能映射相互映射的对象和属性,不会将订单实体意外映射到客户DTO等。
  3. 在构建时清除错误报告,如果映射不完整(并非所有目标属性都已映射)映射不正确(找不到合适的映射方法或类型转换)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容