当前位置: 首页 > 科技观察

Vo2dto方法一共有12个,BeanUtil.copyProperties压测数据最好!

时间:2023-03-16 22:09:33 科技观察

1.前言是什么?您的代码仅可用?没有技术深度,没有知识储备,没有经验积累,怎么写代码?百度,遇到问题请到这里搜索。然后查了一块,不管是什么原理,适合什么样的场景,先贴到自己的工程里,看看,能跑,能跑。那么这样的代码只是一个可用的交付,根本没有一定的质量保证,更谈不上数据结构、算法逻辑和设计模式,那么看编程资料的LeetCode就全没了。当你觉得自己看了很多资料不知道怎么用的时候,你会说什么,真正的卷,你已经学会了。但其实,我并不认为深挖技术,梳理出一套完整的知识体系,收获一点点努力,就是在量。相反,观看技术视频就像看电影一样简单。如果你不写案例,你会认为这本书很好读。脑力思考的无意义缺失和机械的物理重复是体积,甚至是体积。就好像让你用属性复制工具把vo转dto一样。您使用哪一个,Apache的还是Spring的,或者其他什么,哪个最有效?下面我们用数据来验证一下,并提供输出各种案例的使用对比2.性能测试对比在Java系统工程的开发过程中,会存在各层之间的对象转换,如VO、DTO、PO、VO等等,手动获取和设置时间太浪费,还可能出错,所以选择自动化工具会更方便。目前我整理了12种对象属性转换类型,包括:普通getset、json2Json、Apache属性拷贝、Spring属性拷贝、bean-mapping、bean-mapping-asm、BeanCopier、Orika、Dozer、ModelMapper、JMapper、MapStruct接下来我们分别测试了这11种属性转换操作在100、1000、10000、100000、100万次时的性能和时间比较。BeanUtils.copyProperties是大家代码中最常用的工具类,但是只要不是在Apache包下误用,而是使用Spring提供的,对性能基本不会有太大影响。但是如果性能更好的话,可以替代手动get和set,或者MapStruct更好用,因为它本身在编译时生成get和set代码,就像我们写get和set一样。其他一些组件包主要是基于AOP、ASM、CGlib实现的,所以会有相应的性能损失。3、12个转换案例源码:https://github.com/fuzhengwei/guide-vo2dto说明:在案例工程下创建interfaces.assembler包,定义IAssembler1。get\set@ComponentpublicclassGetSetAssemblerimplementsIAssembler{@OverridepublicUserDTOsourceToTarget(UserVOvar){UserDTOuserDTO=newUserDTO();userDTO.setUserId(var.getUserId());userDTO.setUserNickName(var.getUserNickName());userDTO.setCreateTime(var.getCreateTime());returnuserDTO;}}推荐度:★★★☆☆成绩:★★★★★意思:手写点评:其实这个方法也是日常生活中用的最多的。性能肯定不错,就是操作起来有点麻烦。尤其是大量带有属性的VO对象转为DTO对象时。但其实也有一些快捷的操作方法。例如,您可以通过Shift+Alt选择所有属性,然后通过Shift+Tab将它们合并为一列。然后用Alt选中这一列,粘贴userDTO。最后切换到最后加上括号和分号,最后格式化一下就大功告成了。2.json2Json@ComponentpublicclassJson2JsonAssemblerimplementsIAssembler{@OverridepublicUserDTOsourceToTarget(UserVOvar){StringstrJson=JSON.toJSONString(var);returnJSON.parseObject(strJson,UserDTO.class);}}推荐度:☆☆☆☆☆性能:☆☆☆☆☆☆☆☆方法:将对象转为JSON字符串,再将JSON转为另一个对象。try{BeanUtils.copyProperties(userDTO,var);}catch(IllegalAccessException|InvocationTargetExceptione){e.printStackTrace();}returnuserDTO;}}推荐:☆☆☆☆☆性能:★☆☆☆☆手段:由内省获得mechanismClasspropertiesforassignmentoperations点评:有坑,兼容性cross,不推荐4.SpringcopyProperties@ComponentpublicclassSpringCopyPropertiesAssemblerimplementsIAssembler{@OverridepublicUserDTOsourceToTarget(UserVOvar){UserDTOuserDTO=newUserDTO();BeanUtils.copyProperties(var,userDTO);returnuserDTO;}}推推荐度:★★★☆☆性能:★★★★☆意思:Introspector机制获取类的属性进行赋值操作不会出错,基本上不会有问题5.BeanMapping@ComponentpublicclassBeanMappingAssemblerimplementsIAssembler{@OverridepublicUserDTOsourceToTarget(UserVOvar){UserDTOuserDTO=newUserDTO();BeanUtil.copyProperties(var,userDTO);returnuserDTO;}}推荐:★★★☆☆☆性能:★★★☆☆表示:属性复制点评:性能一般);returnuserDTO;}}推荐度:★★★☆☆性能:★★★★☆含义:基于ASM字节码框架点评:与普通BeanMapping相比,性能有所提升,可以使用。7.BeanCopier@ComponentpublicclassBeanCopierAssemblerimplementsIAssembler{@OverridepublicUserDTOsourceToTarget(UserVOvar){UserDTOuserDTO=newUserDTO();BeanCopierbeanCopier=BeanCopier.create(var.getClass(),userDTO.getClass(),false);beanCopier.copyuserDTO,null);returnuserDTO;}}推荐度:★★★☆☆性能:★★★★☆意思:根据CGlib字节码操作生成get和set方法点评:整体性能很好,使用不复杂,可以8.Orika@ComponentpublicclassOrikaAssemblerimplementsIAssembler{/***构造一个MapperFactory*/privatestaticMapperFactorymapperFactory=newDefaultMapperFactory.Builder().build();static{mapperFactory.classMap(UserDTO.class,UserVO.class).field("userId","userId")//字段不一致时可以指定。://orika-mapper.github.io/orika-docs/推荐度:★★☆☆☆性能:★★★☆☆方法:根据字节码生成映射对象评论:测试性能不是太突出,如果使用优化MapperFactory的构建Bean对象9.Dozer@ComponentpublicclassDozerAssemblerimplementsIAssembler{privatestaticDozerBeanMappermapper=newDozerBeanMapper();@OverridepublicUserDTOsourceToTarget(UserVOvar){returnmapper.map(var,UserDTO.class);}}官网:http://dozer.sourceforge.net/documentation/gettingstarted.html推荐度:★☆☆☆☆性能:★★☆☆☆含义:属性映射框架,递归复制对象点评:性能有点差,不建议使用10.ModelMapper@ComponentpublicclassModelMapperAssemblerimplementsIAssembler{privatestaticModelMappermodelMapper=newModelMapper();static{modelMapper.addMappings(newPropertyMap(){@Overrideprotectedvoidconfigure(){//属性值不同,可以操作map().setUserId(source.getUserId());}});}@OverridepublicUserDTOsourceToTarget(UserVOvar){returnmodelMapper.map(var,UserDTO.class);}}官网:http://modelmapper.org推荐度:★★★☆☆性能:★★★☆☆手段:基于ASM字节码实现注释:当转换的对象数量少时性能较好,但如果同时转换大量对象,性能会下降11.JMapperJMapperjMapper=newJMapper<>(UserDTO.class,UserVO.class,newJMapperAPI().add(JMapperAPI.mappedClass(UserDTO.class).add(JMapperAPI.attribute("userId").value("userId")).add(JMapperAPI.attribute("userNickName").value("userNickName")).add(JMapperAPI.attribute("createTime").value("createTime"))));官网:https://github.com/jmapper-framework/jmapper-core/wiki推荐度:★★★★☆性能:★★★★★含义:优雅、高性能和健壮性一体的javabeanmapper评论:速度确实不错,但是和SpringBoot结合起来感觉有点麻烦,可能姿势不对12.MapStruct@Mapper(componentModel="spring",unmappedTargetPolicy=ReportingPolicy.IGNORE,unmappedSourcePolicy=ReportingPolicy.IGNORE)publicinterfaceUserDTOMappingextendsIMapping{/**用于测试的单个案例*/IMappingINSTANCE=Mappers.getMapper(UserDTOMapping.class);@Mapping(target="userId",source="userId")@Mapping(target="createTime",dateFormat="yyyy-MM-ddHH:mm:ss")@OverrideUserDTOsourceToTarget(UserVOvar1);@Mapping(target="userId",source="userId")@Mapping(target="createTime",dateFormat="yyyy-MM-ddHH:mm:ss")@OverrideUserVOtargetToSource(UserDTOvar1);}官网:https://github.com/mapstruct/mapstruct推荐度:★★★★★性能:★★★★★意思:编译时直接生成对应的get和set,手写代码一样的注释:速度速度非常快,运行时不需要处理,结合框架使用方便。思路是在编译前生成对应的get和set,就像手写的一样,所以推荐我最喜欢的MapStruct,用起来比较舒服,一是从功能的扩展性,易用性和兼容性。不管是哪种用途,一定要做好完整的测试和验证,不要一上来就复制粘贴,否则可能早挖坑了,当然也不一定是会填坑的兄弟。