蔡昊 - 如何高效而优雅的进行对象转换

简介: 简介随着分层结构和DDD设计思想的普及,我们在后端开发过程中,会使用到VO/DO/DTO等等各种类型的模型对象,对象的转换工作也随着变得越来越多。而这种工作技术含量不高,却容易过多的出现在编码里,处理不当也会出现各种问题,那么如何更加高效而优雅的进行类型转换呢?且花几分钟了解下笔者接下来要讲的一款Java代码生成器MapStruct——创建实现Java Bean之间转换的扩展映射器!

MapStruct的优点

首先,我们了解下常见的转换对象方法:

// 1. getter+setter 这种方式会产生大量无意义工作和重复代码
// 2. BeanUtils      
这种方式适用处理简单结构的转换,遇到字段名称不对应等情况,仍需要额外的处理
BeanUtils.copyProperties(Object source,Object target)

MapStruct特点

•            简单、自动化

•            编译时生成映射,确保运行时性能

•            只需要创建接口,大大减少样板代码的编码工作

MapStruct的使用

1. 引包与配置

<properties>                
   <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
</properties>

<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct</artifactId>
   <version>${org.mapstruct.version}</version>
</dependency>
<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-processor</artifactId>
   <version>${org.mapstruct.version}</version>
</dependency>

*最新maven版本:https://mvnrepository.com/artifact/org.mapstruct/mapstruct

2. 编码及基本使用

先看下需要转换的两个类,这里简化模型,仅仅以VODO做为案例:

@Data
publicclass UserVO{
   privateLong id;
   privateString userName;
   privateString email;
   privateInteger gender;
}

@Data
@TableName(value ="User")
publicclass User implementsSerializable{
   privatestaticfinallong serialVersionUID =1L;

   @TableId(type = IdType.AUTO)
   privateLong id;
   privateString name;
   privateString email;
   privateString createdDate;
   privateString updatedDate;
   privateInteger gender;
}

第一步:下面是新建一个转换类的接口:

/**
* UserTransfer
*
* @author CaiHao
*@since 2022/3/1011:42
*/
//
标记为映射接口,@Mapper允许接口mapstruct-processor在编译期启动
@Mapper
publicinterface UserTransfer {

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

   //
映射名称不同的字段
   @Mapping(source ="userName", target ="name")
   //
声明转换方法
   User toDo(UserVO vo);

   @Mapping(source ="name", target ="userName")
   UserVO toVo(User user);

   // list
转换
   List<User>toDo(List<UserVO> voList);

   List<UserVO>toVo(List<User> doList);
}

第二步:如何使用

// 方式一:通过INSTANCE实现访问
User user = UserTransfer.INSTANCE.toDo(tom);

或使用@Mapper(componentModel = "spring")

// 方式二:注入UserTransfer userTransfer;
User user = userTransfer.toDo(tom);

3. 拓展应用

情况一:变量为实体(嵌套bean

@Data
@Builder
@AllArgsConstructor
publicclass EmployeeVO {
   privateLong id;
   privateString empName;
   privateString gender;

   private Contact contact;
}

@Data
publicclass Contact {
   privateString address;
   privateString phone;
   privateString email;
}

@Data
@Builder
publicclass UserVO {
   privateLong id;
   privateString userName;
   privateString email;
   privateInteger gender;
   privateString address;
   privateString phone;
}

@Mapper
publicinterface UserTransfer {
   UserTransfer INSTANCE = Mappers.getMapper(UserTransfer.class);
   /**
    * UserVO
转换成EmployeeVO
    *
    * @param userVO userVO
    *@return EmployeeVO EmployeeVO
    */
   @Mapping(source ="userName", target ="empName")
   @Mapping(source ="email", target ="contact.email")
   @Mapping(source ="address", target ="contact.address")
   @Mapping(source ="phone", target ="contact.phone")
   EmployeeVO toEmployeeVO(UserVO userVO);
}

EmployeeVO employeeVO = UserTransfer.INSTANCE.toEmployeeVO(tom);

情况二: 类型转换、映射合成

publicclass User{    
   privateString updatedDate;
   privateInteger gender;
}

publicclass UserVO {
   privateDate gmtCreate;
   privateString gender;
}

@Mappings({
@Mapping(target ="gender", expression="java(java.lang.String.valueOf(user.getGender()))"),
@Mapping(source ="createdDate", target ="gmtCreate", dateFormat ="yyyy-MM-dd HH:mm")
})
UserVO toVo(User user);

mapstruct的应用场景广泛,如转换、处理第三方服务结果集,同时配合Lombok注解,可以发挥出更好的效果。

*关于更多高级属性和方法,可以查看官方文档

相关文章
|
JavaScript 前端开发 PHP
【Vue+NodeJS】vue路由及NodeJS环境搭建(Windows版)
Node.js是一个基于Chrome V8引擎构建的JavaScript运行时环境使用了一个事件驱动、非阻塞式I/O 的模型;可以让JavaScript在服务器端运行,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。相对于传统的JavaScript运行环境(如浏览器),Node.js具有以下特点:事件驱动:Node.js使用事件驱动的非阻塞I/O模型,使得在处理大量并发请求时效率更高。单线程。
|
缓存 JavaScript Cloud Native
阿里云发布 Spring Boot 新脚手架,真香
本文,围绕 spring initializr 框架,以 start.spring.io 为例,全面的给大家介绍如何使用和扩展这个框架,以及背后的运行原理。
56613 1
阿里云发布 Spring Boot 新脚手架,真香
|
6月前
|
人工智能 算法 数据处理
算法为舟 思想为楫:AI时代,创作何为?
本文探讨了AI时代创作领域的变革与挑战,分析了人类创作者的独特价值,并展望了未来创作的新图景。随着生成式AI技术的发展,创作的传统认知被颠覆,评价体系面临革新。然而,人类创作者凭借批判性思维、情感智能、创意直觉和伦理自觉,依然具有不可替代的价值。文章呼吁创作者转变思维,从竞争走向合作,提升复合能力,关注作品的社会影响,并持续学习进化。在AI助力下,创作将更加民主化、多样化,推动文明进步。最终,人机协同或将成为未来创作的核心模式,共同开创文化发展的新纪元。
|
11月前
|
前端开发 容器
CSS 中几种常用的换行方法
CSS 中几种常用的换行方法
262 1
|
10月前
|
自然语言处理 并行计算 数据可视化
免费开源法律文档比对工具:技术解析与应用
这款免费开源的法律文档比对工具,利用先进的文本分析和自然语言处理技术,实现高效、精准的文档比对。核心功能包括文本差异检测、多格式支持、语义分析、批量处理及用户友好的可视化界面,广泛适用于法律行业的各类场景。
473 1
|
存储 Linux
为什么通过clear_refs可以使进程触发缺页?
为什么通过clear_refs可以使进程触发缺页?
|
存储 负载均衡 监控
|
分布式计算 并行计算 数据处理
|
应用服务中间件 nginx 容器
upstream server temporarily disabled while connecting to upstream(记录bug)
upstream server temporarily disabled while connecting to upstream(记录bug)
533 0
|
机器学习/深度学习 人工智能 算法
推荐系统召回算法及架构说明
阿里巴巴技术专家傲海为大家带来推荐系统召回算法及架构说明的介绍。内容包括召回模块在推荐系统中的位置,召回算法的介绍,什么是协同过滤,以及向量召回架构的说明。
推荐系统召回算法及架构说明