实体拷贝工具大汇总,你还在用BeanUtils? 赶紧来学一学吧
我们在项目当中,经常会遇到实体拷贝的情况,必须把DO拷贝到BO, BO拷贝到VO等等,这个时候,如果我们还是单纯的使用get/set 会发现,代码可能会变得非常的臃肿,但不可置疑的是get/set不会有太大的坑。 所以实体拷贝工具有时候就成了程序的标配。今天就给大家介绍汇总一下常用的实体拷贝工具,并使用非常简单的例子来测试一下他们的性能,由于没有大量场景的测试,所以测试结果不代表最终结果,仅供大家参考。 还有就是我这里面汇总的工具,不像很多其他文章那样,都是一些比较老的工具,毕竟2020年了,这里囊括了dozer ,easyMapper, modelMapper等比较新的工具介绍给大家。
代码说明: 在下面的工具介绍中,我们会使用每种工具,拷贝一个简单的对象实体,并测试执行时间。所以我们先准备两个类结构一致的对象,然后给其中的一个对象赋值,将其拷贝给另一个对象。
源对象:
@Data
public class Person {private int id;private String name;private Boolean vipFlag;private BigDecimal price;private Date createTime;private LocalDateTime updateTime;
}
目标对象
@Data
public class PersonVO {private int id;private String name;private Boolean vipFlag;private BigDecimal price;private Date createTime;private LocalDateTime updateTime;
}
给Person对象赋值,然后通过下面的工具类拷贝到PersonVO中
public class BeanCopyDemo {@Testpublic void test() throws Exception{// 先设置一个有值的对象Person p = new Person();p.setId(1);p.setName("张三");p.setPrice(new BigDecimal("100"));p.setVipFlag(true);p.setCreateTime(new Date());p.setUpdateTime(LocalDateTime.now());System.out.println(p);// 各工具的拷贝方法......}
}
一. apache BeanUtils:
这款工具不用多介绍了,相信很多人最开始做拷贝的时候都会用过,我这里不详细讲了,也极度不推荐大家使用,因为在阿里巴巴的编程规范中也已经不推荐使用这个方法了,原因就是效率太差,所以也不推荐大家使用,如果大家非要用apache的话,可以使用PropertyUtils, 效率会比这个工具要高一些。
这个类的用法给大家截个图:
这时候可以看到这个方法的调用已经有红线了,原因就是我安装的阿里巴巴插件检测到了这个方法,直接不建议使用了。 另外他执行拷贝所消耗的时间确实很长
依赖:
<dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version>
</dependency>
二. 使用spring中的BeanUtils
说下这个BeanUtils,要注意的是,他的类名和上面说的那个类名是一模一样的,区别就是一个是apache的,一个是spring的, spring的这个只要你的项目中有spring就可以用,不需要单独导包。同时要注意他和上面那个类的用法十分相似,区别就是参数是相反的,另外这个类的执行效率也还不错,所以如果不想引入其他依赖的时候,可以使用这个类来替代上面的apache的方式。
// 方式2: 使用springBeanUtilsstart = System.currentTimeMillis();p2 = new PersonVO();org.springframework.beans.BeanUtils.copyProperties(p, p2);// spring BeanUtils 耗时:56毫秒System.out.println("spring BeanUtils 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p2);System.out.println("----------------------------");
这段代码和上面的是接上的,由于两个类名相同,这里只能使用全类名进行调用,尤其zhuyi9参数顺序,有值的在前面,目标在后面。和上面的方法区分开。
三. cglib BeanCopier
接下来介绍的是cglib中的BeanCopier类,这个是cglib的, cglib我想大家应该知道吧,不知道的是不是也有点耳熟,一般面试的时候经常会被问道,spring中的aop的实现原理,一种是使用java中的动态代理,还有是cglib,cglib是通过底层字节码的方式实现的。同理他里边的BeanCopier在拷贝类的时候也是通过字节码的方式实现的,所以效率很高。不夸张的说,这个类应该是众多实体拷贝的方式中综合成绩最高的,我参考的很多其他文章也都是这个类的效率第一。 所以如果对于效率要求比较高的情况下,建议选择这个类,同时要注意,这个类在使用的时候有一个初始化的过程,我们可以把初始化的对象缓存起来,网上有比较多的案例,大家可以参考,去掉初始化的时间,我用这个类拷贝的结果是 0毫秒,相当于瞬间完成。
// 方式3: 使用BeanCopier 是cglib提供的p2 = new PersonVO();start = System.currentTimeMillis();// cglib BeanCopier 不算初始化耗时:0毫秒 算上初始化40毫秒BeanCopier beanCopier = BeanCopier.create(Person.class, PersonVO.class, false);// p 是源 p2 是目标beanCopier.copy(p, p2, null);System.out.println("cglib BeanCopier 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p2);System.out.println("----------------------------");
四. Dozer
dozer: 这是一个实体拷贝的框架,相当于是专门干这件事的,我相信应该有不少朋友用过,因为我们在实体拷贝的过程中一直存在一个痛点就是深拷贝。上面几种工具都是做的浅拷贝,相当于你的类中如果还嵌套了其他对象是拷贝不了的。而dozer是支持深拷贝的,并且支持不同字段名名字的映射。比如你想把address 拷贝到 addr 上这种场景也是支持的。同时dozer有一个问题,在这必须提一下,就是dozer本身不支持jdk8 中的LocalDateTime的,使用这个类型会报错。如果非要使用,我们可以在依赖一个dozer支持jdk8的插件,所以比较麻烦,另外dozer的效率确实不高,感觉有点太重量级了,也有点老了,整体实力和第一个差不多。
依赖:
<!-- dozer -->
<dependency><groupId>net.sf.dozer</groupId><artifactId>dozer</artifactId><version>5.4.0</version>
</dependency>
<dependency><groupId>io.craftsman</groupId><artifactId>dozer-jdk8-support</artifactId><version>1.0.6</version>
</dependency>
案例:
//方式4: dozer: 一个实体拷贝框架,支持深拷贝,可自定义映射(名称不同的字段间进行拷贝)// 需引入jar包,需兼容jdk8// 并且不支持localDateTimeDozerBeanMapper mapper = new DozerBeanMapper();mapper.setMappingFiles(Collections.singletonList("dozerJdk8Converters.xml"));start = System.currentTimeMillis();PersonVO p3 = mapper.map(p, PersonVO.class);// dozer 耗时:119毫秒System.out.println("dozer 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p3);
五. ModelMapper.
这也是一个实体拷贝类框架,需要引入依赖, 支持自定义映射, 支持List, Map拷贝,用法和dozer极为相似,在我的测试中效果表现很好,很快。比较推荐。
依赖:
<dependency><groupId>org.modelmapper</groupId><artifactId>modelmapper</artifactId><version>2.3.0</version>
</dependency>
用法:
// 方式5: ModelMap// 需引入jar: org.modelmapper// 支持自定义映射,支持List mapstart = System.currentTimeMillis();ModelMapper modelMapper = new ModelMapper();PersonVO p4 = modelMapper.map(p, PersonVO.class);// modelMapper 耗时:37毫秒System.out.println("modelMapper 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p4);
拷贝集合用法演示:
List<EventDO> eventList = eventService.list(new LambdaQueryWrapper<EventDO>().in(EventDO::getEventCode, eventCodeArr));
ModelMapper modelMapper = new ModelMapper();
List<EvenVO>list = modelMapper.map(eventList, new TypeToken<List<EventVO>>() {}.getType());
六. EasyMapper用法:
easyMapper也是干这个活的,百度出品的,但是说实话效率没有ModeMapper快,比dozer快
详细用法:
http://neoremind.com/2016/08/easy-mapper-%E4%B8%80%E4%B8%AA%E7%81%B5%E6%B4%BB%E5%8F%AF%E6%89%A9%E5%B1%95%E7%9A%84%E9%AB%98%E6%80%A7%E8%83%BDbean-mapping%E7%B1%BB%E5%BA%93/
引入依赖:
<dependency><groupId>com.baidu.unbiz</groupId><artifactId>easy-mapper</artifactId><version>1.0.4</version>
</dependency>
用法:
// 方式6: EasyMapper:// http://neoremind.com/2016/08/easy-mapper-%E4%B8%80%E4%B8%AA%E7%81%B5%E6%B4%BB%E5%8F%AF%E6%89%A9%E5%B1%95%E7%9A%84%E9%AB%98%E6%80%A7%E8%83%BDbean-mapping%E7%B1%BB%E5%BA%93/start = System.currentTimeMillis();PersonVO p5 = MapperFactory.getCopyByRefMapper().mapClass(Person.class, PersonVO.class).registerAndMap(p, PersonVO.class);// easyMapper 耗时:88毫秒System.out.println("easyMapper 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p5);
七. orika: 表现也很一般。
引入依赖:
<dependency><groupId>ma.glasnost.orika</groupId><artifactId>orika-core</artifactId><version>1.5.2</version><!-- or latest version --></dependency>
用法:
// 6. orika:125msstart = System.currentTimeMillis();DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();MapperFacade orikaMapper = mapperFactory.getMapperFacade();PersonVO p6 = orikaMapper.map(p, PersonVO.class);System.out.println("orika 耗时:" + (System.currentTimeMillis() - start) + "毫秒");System.out.println("拷贝之后结果:" + p6);
好了,目前比较主流的拷贝方法就大家介绍到这里。
如果追求速度,果断选择 cdlib, 并将初始化过程缓存起来,方便复用
如果追求实用方便,能深拷贝,自定义拷贝,拷贝集合,推荐选择ModelMapper.
本测试结果仅供参考, 未进行复杂多维度多条件多场景测试,不代表权威观点。
实体拷贝工具大汇总,你还在用BeanUtils? 赶紧来学一学吧相关推荐
- 免费H5页面制作工具大汇总
营销代有手段出,各领风骚数百天.要说现在哪些营销方式最能传播,屡屡刷爆朋友圈的H5页面肯定就是首当其冲的,提到H5页面,就立马想到"围住神经猫",上线微信朋友圈3天的时间便创造了用 ...
- .NET开发常用工具大汇总
1.Visual Studio Visual Studio Productivity Power tool:Visual Studio专业版(及以上)的扩展,具有丰富的功能,如快速查找,导航解决方案, ...
- IOS开发工具大汇总(一)
1.crash分析工具 1.1 lldb+汇编分析: 最原生也是最强大的工具 1.2 Cycript: 参考文章:http://www.wildpointer.cn/ios-security-cy ...
- 年轻人不讲武德!200个网络渗透测试工具大汇总
最近有粉丝私信我说能不能写一期资料整理的文章 那么....它来了! 以下工具适合渗透测试人员,安全研究人员. 可以通过以下命令检查所有的工具: git clone --recursive https: ...
- Java开源建站工具大汇总
美国程序员Jon Scott Stevens,公布了他的创业公司所使用的开发工具清单. 他的语言平台是Java,开发项目是一个网站(还未上线).所用到的工具都是开源的, 可以免费得到. 在 ...
- 画出漂亮的神经网络图,神经网络可视化工具大汇总
分享几款画神经网络图神器,喜欢欢迎点赞.关注.收藏. 1. draw_convnet 一个用于画卷积神经网络的Python脚本 https://github.com/gwding/draw_convn ...
- 视频虚拟主播怎们搞?体验报告全记录;一图掌握SD应用精髓;Chat效率工具大汇总;品牌营销进入AI时代 | ShowMeAI日报
- Windows中常用文件拷贝工具的评测和对比 1
对于Windows用户,拷贝文件是再常用不过的功能.打开文件浏览器(FileExplorer),把一个盘符的一个文件夹拖拽到另一个盘符下面是非常简单的操作.这样的文件拖拽操作在两端都是本地盘的情况下速 ...
- 中文实体命名识别工具使用汇总:Stanza、LAC、Ltp、Hanlp、foolnltk、NLTK、BosonNLP
实体命名识别 相关知识 Stanford CoreNLP 命名实体识别 一.简介: 二.java版本使用 三.python版本使用 NLTK 命名实体识别 一.简介: 二.搭建环境 三.nltk使用 ...
最新文章
- 路径名导致的异常:javax.imageio.IIOException: Can‘t read input file!
- ROS系统 创建工作空间与功能包
- 三步修改CodeBlocks主题
- 2.5.jieba分词工具、Jieba安装、全模式/精确模式、添加自定义词典、关键词抽取、词性标注、词云展示
- 使用WIM格式进行WES 7 (windows embedded standard )的安装
- XMind软件简易使用教程
- 2013Esri全球用户大会QA之Web GIS
- python实现登录抓取_[Python]网络爬虫(五):利用POST方式登录账号抓取
- OpenGL开启Gouraud明暗处理,减少马赫夫效应
- java 调用 yed 绘制 流程图_用 yEd Graph Editor 绘制流程图(2)
- Java程序员面试笔试宝典-数据库原理(三)
- 计算机无法设置双屏显示,win10无法设置双屏显示怎么办_win10系统设置双屏显示失败如何解决...
- AMC数学考试能用计算机吗,重大调整!今年美国数学竞赛AMC考试时间有变化!
- pandas用法小结
- 蓝桥杯java备赛Day3——跳马
- python中_x、__x、__xx__的区别
- Hibernate Criteria对象详解(条件查询)
- C++入门第一阶段——基础篇
- 【附源码】计算机毕业设计JAVA个性化推荐的扬州农业文化旅游管理平台
- C# SuperSocket 手把手教你入门 傻瓜教程---1(服务器单向接收客户端发送数据)
热门文章
- layui调用自定义方法提示未定义的解决办法
- 某知名IT公司最近的一道笔试编程题
- iphone 开发 窗口(UIWindow) 与视图(UIView)之间以及整个程序间的关系,深层解析
- 【天池学习赛】淘宝母婴购物数据可视化分析
- linux中top指令,Linux下top命令详解
- 苹果最新财报看点:中国区销量下滑
- echarts展示国内各省各市地图
- 推箱子经典游戏源码 附成品 易语言源码
- 【老生谈算法】matlab绘制三维等高线地形图——三维等高线
- PADS Layout VX.2.3 出Gerber文件时遇到一个奇怪的现象