点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!

作者:阿进的写字台

https://www.cnblogs.com/homejim/

第一次看到 MapStruct 的时候, 我个人非常的开心。因为其跟我内心里面的想法不谋而合。

1 MapStruct 是什么?

1.1 JavaBean 的困扰

对于代码中 JavaBean之间的转换, 一直是困扰我很久的事情。

在开发的时候我看到业务代码之间有很多的 JavaBean 之间的相互转化, 非常的影响观感, 却又不得不存在。我后来想的一个办法就是通过反射, 或者自己写很多的转换器。

第一种通过反射的方法确实比较方便, 但是现在无论是 BeanUtilsBeanCopier 等在使用反射的时候都会影响到性能。虽然我们可以进行反射信息的缓存来提高性能。

但是像这种的话, 需要类型和名称都一样才会进行映射, 有很多时候, 由于不同的团队之间使用的名词不一样, 还是需要很多的手动 set/get 等功能。

第二种的话就是会很浪费时间, 而且在添加新的字段的时候也要进行方法的修改。不过, 由于不需要进行反射, 其性能是很高的。

1.2 MapStruct 带来的改变

MapSturct 是一个生成类型安全, 高性能且无依赖的 JavaBean 映射代码的注解处理器(annotation processor)。

抓一下重点:

  1. 注解处理器

  2. 可以生成 JavaBean 之间那的映射代码

  3. 类型安全, 高性能, 无依赖性

从字面的理解, 我们可以知道, 该工具可以帮我们实现 JavaBean 之间的转换, 通过注解的方式。

同时, 作为一个工具类,相比于手写, 其应该具有便捷, 不容易出错的特点。

MapStruct 入门

入门很简单。我是基于 Maven 来进行项目 jar 包管理的。

2.1 引入依赖

<properties><org.mapstruct.version>1.3.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>

2.2 创建entity和dto对象

该类是从 github 某个订单系统里面拿下来的部分。

@Data
public class Order {/***订单id*/private Long id;/*** 订单编号*/private String orderSn;/*** 收货人姓名/号码*/private String receiverKeyword;/*** 订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单*/private Integer status;/*** 订单类型:0->正常订单;1->秒杀订单*/private Integer orderType;/*** 订单来源:0->PC订单;1->app订单*/private Integer sourceType;
}

对应的查询参数

@Data
public class OrderQueryParam {/*** 订单编号*/private String orderSn;/*** 收货人姓名/号码*/private String receiverKeyword;/*** 订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单*/private Integer status;/*** 订单类型:0->正常订单;1->秒杀订单*/private Integer orderType;/*** 订单来源:0->PC订单;1->app订单*/private Integer sourceType;}

2.3 写 Mapper

Mapper 即映射器, 一般来说就是写 xxxMapper 接口。

当然, 不一定是以 Mapper 结尾的。只是官方是这么写的。在本入门例子中,对应的接口如下

import com.homejim.mapstruct.dto.OrderQueryParam;
import com.homejim.mapstruct.entity.Order;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;@Mapper
public interface OrderMapper {OrderQueryParam entity2queryParam(Order order);}

简单的映射(字段和类型都匹配), 只有一个要求, 在接口上写 @Mapper 注解即可。

然后方法上, 入参对应要被转化的对象, 返回值对应转化后的对象, 方法名称可任意。

2.4 测试

写一个测试类测试一下。

@Test
public void entity2queryParam() {Order order = new Order();order.setId(12345L);order.setOrderSn("orderSn");order.setOrderType(0);order.setReceiverKeyword("keyword");order.setSourceType(1);order.setStatus(2);OrderMapper mapper = Mappers.getMapper(OrderMapper.class);OrderQueryParam orderQueryParam = mapper.entity2queryParam(order);assertEquals(orderQueryParam.getOrderSn(), order.getOrderSn());assertEquals(orderQueryParam.getOrderType(), order.getOrderType());assertEquals(orderQueryParam.getReceiverKeyword(), order.getReceiverKeyword());assertEquals(orderQueryParam.getSourceType(), order.getSourceType());assertEquals(orderQueryParam.getStatus(), order.getStatus());}

测试通过, 没有任何的问题。

3 MapStruct 分析

上面中, 我写了3个步骤来实现了从 Order 到 OrderQueryParam 的转换。

那么, 作为一个注解处理器, 通过MapStruct 生成的代码具有怎么样的优势呢?

3.1 高性能

这是相对反射来说的, 反射需要去读取字节码的内容, 花销会比较大。而通过 MapStruct 来生成的代码, 其类似于人手写。速度上可以得到保证。

前面例子中生成的代码可以在编译后看到。在 target/generated-sources/annotations 里可以看到。

生成的代码

对应的代码

@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2019-08-02T00:29:49+0800",comments = "version: 1.3.0.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)"
)
public class OrderMapperImpl implements OrderMapper {@Overridepublic OrderQueryParam entity2queryParam(Order order) {if ( order == null ) {return null;}OrderQueryParam orderQueryParam = new OrderQueryParam();orderQueryParam.setOrderSn( order.getOrderSn() );orderQueryParam.setReceiverKeyword( order.getReceiverKeyword() );orderQueryParam.setStatus( order.getStatus() );orderQueryParam.setOrderType( order.getOrderType() );orderQueryParam.setSourceType( order.getSourceType() );return orderQueryParam;}
}

可以看到其生成了一个实现类, 而代码也类似于我们手写, 通俗易懂。

3.2 易于 debug

在我们生成的代码中, 我们可以轻易的进行 debug。

易于 DEBUG

在使用反射的时候, 如果出现了问题, 很多时候是很难找到是什么原因的。

3.3 使用相对简单

如果是完全映射的, 使用起来肯定没有反射简单。用类似 BeanUtils 这些工具一条语句就搞定了。但是,如果需要进行特殊的匹配(特殊类型转换, 多对一转换等), 其相对来说也是比较简单的。

基本上, 使用的时候, 我们只需要声明一个接口, 接口下写对应的方法, 就可以使用了。当然, 如果有特殊情况, 是需要额外处理的。

3.4 代码独立

生成的代码是对立的, 没有运行时的依赖。

热门内容:
  • 别说,Cerebro还真好用!老板再也不用担心ES集群了

  • 用了3年Apollo,这次我选择了Nacos,原因不多说了

  • 为什么强烈推荐 Java 程序员使用 Google Guava 编程!

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡

还在用 BeanUtils来做对象转换吗?快试试 MapStruct吧相关推荐

  1. Java对象转换方案分析与mapstruct实践

    简介: 随着系统模块分层不断细化,在Java日常开发中不可避免地涉及到各种对象的转换,如:DO.DTO.VO等等,编写映射转换代码是一个繁琐重复且还易错的工作,一个好的工具辅助,减轻了工作量.提升开发 ...

  2. java dozer map转对象_对象转换利器之Dozer

    在Java的世界中,经常会涉及到需要在2个对象中进行转换,比如说: 调用SOAP Web服务,需要把自己的Domain对象转换为Soap服务的Jaxb对象请求, 在分层级SOA架构中,2个层级之间Do ...

  3. 芋道 Spring Boot 对象转换 MapStruct 入门

    点击上方"芋道源码",选择"设为星标" 做积极的人,而不是积极废人! 源码精品专栏 原创 | Java 2020 超神之路,很肝~ 中文详细注释的开源项目 RP ...

  4. android 中XML和对象转换利器Xstream的使用

    XStream框架: 虽说pull dom dom4j等优秀的xml解析工具使用非常广泛,但对于复杂庞大的数据交互来说,使用它们无疑让你倍加痛苦,你可能大部分精力都放在无聊繁琐的解析和拼装上,如果接口 ...

  5. [Unity ECS] 游戏对象转换和子场景 [1]

      游戏只是关于玩家输入改变数据,然后看到不同呈现的事物,因此玩得开心.这些数据是使用 Unity 的 WYSIWYG 工具在scene设计的.但是那些基于 GameObject 的数据与 ECS 不 ...

  6. 自定义java对象转换工具类

    背景 项目中经常有VO.PO.DTO等之间转换,由于apache工具类中BeanUtils.copyProperties及Json序列化反序列化方式转换性能比较低(阿里巴巴规范检查有提示不建议采用). ...

  7. Java中的dozer对象转换

    Java中的dozer对象转换 1.dozer介绍 Dozer是Java Bean到Java Bean映射器,它以递归方式将数据从一个对象复制到另一个对象. dozer是用来对两个对象之间属性转换的工 ...

  8. 我写了个IDEA开源插件,vo2dto 一键生成对象转换

    头炸,po2vo.vo2do.do2dto,一堆对象属性,取出来塞进来.要不是为了 DDD 架构下的各个分层防腐,真想一竿子怼下去. 那上 BeanUtils.copyProperties 呀,其实对 ...

  9. Java对象转换最佳方案

    系统变的复杂,系统的层次划分越来越细,边界也越来越明确. 然后每一层之间一般都有自己要处理的领域对象,统称为pojo一般在model或者domain包下(类的后缀不能为pojo). 常见的一些模型类型 ...

最新文章

  1. leetcode-回文数(简单)
  2. 转:入侵网站必备-sql server
  3. 二进制在计算机电路中得到广泛的应用,电子技术与单片机的发展应用2喜欢就下吧(全文完整版)...
  4. JS:1.3,函数(function)
  5. 如何锻炼膝盖和膝盖周围肌肉_我的分享膝盖照片的社交网络将如何拯救世界
  6. ProgressDialog弹出时的底色变暗(转)
  7. python输入y继续运行_Python二三事 - 接触Python(x,y)
  8. 牛逼!9种不同的方法帮助你提高国内访问Github的速度到2MB/s以上...
  9. pytorch模型初始化
  10. Silverlight-style
  11. 计算机软件销售收入会计,嵌入式软件产品销售额如何计算
  12. Web前端JSP面试题
  13. Origin软件绘制柱形图
  14. property_get和property_set使用方法
  15. 多视图信息瓶颈表征学习
  16. Java 根据输入的a、b、c,计算三角形面积和周长。根据程序上下文以及输入输出样例,填写程序空白,使程序完整
  17. windows10安装Python 3.xx.xx,勾选 Download debugging symbols或Download debug binari两项安装失败解决办法
  18. mysql的pv跟pc_PC板PV板PVC板PPV板区别与用途
  19. 前台使用viewbag
  20. 敢用这张图片做“壁纸”手机秒变砖!

热门文章

  1. Python代码选中文乱码
  2. python的深拷贝与浅拷贝
  3. Spring 学习笔记
  4. ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)
  5. Java基础知识强化之IO流笔记41:字符流缓冲流之复制文本文件案例02(使用 [ newLine() / readLine() ] )(重要)...
  6. Oracle面试问题汇总
  7. [PyQt4]项目开发中遇到的错误与解决办法
  8. 各大IT公司笔试真题汇总开发人员一定要加入收藏夹的网站(收藏)
  9. Cookie注入是怎样产生的
  10. 刻意练习:LeetCode实战 -- Task05. 最接近的三数之和