成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

12種 Vo2dto 方法,就 BeanUtil.copyProperties 壓測數據最拉跨!

開發 前端
就像讓你用一個屬性拷貝工具,把vo轉成dto,你用了哪呢,是 Apache 的還是 Spring 的,還是其他的什么,哪個效率最高?

[[427957]]

一、前言

為哈么,你的代碼也就僅僅是能用而已?

沒有技術深度、短缺知識儲備、匱乏經驗積累的前提下,怎么寫代碼?百度呀,遇到問題這搜一點,那查一塊,不管它是什么原理還是適合哪種場景,先粘貼到自己的工程里,看,能跑了,能跑就行。那這樣的代碼也就僅僅是能用程度的交付,根本沒有一定的質量保證,也更別提數據結構、算法邏輯和設計模式了,那看的編程資料刷的LeetCode,全歇菜了。

當你感覺看了很多資料又不會用的時候,會說什么,真卷,都學到這樣了。但其實我并不覺對技術的深度挖掘、梳理全套的知識體系,一點點耕耘一點點收獲是在卷。反而把看技術視頻當成看電影一樣輕松,不寫案例就以為書看會了的爽,沒有意義的缺少腦力思考機械式體力重復,才是卷,甚至很卷。

就像讓你用一個屬性拷貝工具,把vo轉成dto,你用了哪呢,是 Apache 的還是 Spring 的,還是其他的什么,哪個效率最高?接下來我們來用數據驗證下,并提供出各種案例的使用對比

二、性能測試對比

在 Java 系統工程開發過程中,都會有各個層之間的對象轉換,比如 VO、DTO、PO、VO 等,而如果都是手動get、set又太浪費時間,還可能操作錯誤,所以選擇一個自動化工具會更加方便。

目前我整理出,用于對象屬性轉換有12種,包括:普通的getset、json2Json、Apache屬性拷貝、Spring屬性拷貝、bean-mapping、bean-mapping-asm、BeanCopier、Orika、Dozer、ModelMapper、JMapper、MapStruct 接下來我們分別測試這11種屬性轉換操作分別在一百次、一千次、一萬次、十萬次、一百萬次時候的性能時間對比。

  • BeanUtils.copyProperties 是大家代碼里最常出現的工具類,但只要你不把它用錯成 Apache 包下的,而是使用 Spring 提供的,就基本還不會對性能造成多大影響。
  • 但如果說性能更好,可替代手動get、set的,還是 MapStruct 更好用,因為它本身就是在編譯期生成get、set代碼,和我們寫get、set一樣。
  • 其他一些組件包主要基于 AOP、ASM、CGlib,的技術手段實現的,所以也會有相應的性能損耗。

三、12種轉換案例

源碼:https://github.com/fuzhengwei/guide-vo2dto

描述:在案例工程下創建 interfaces.assembler 包,定義 IAssembler

1. get\set

  1. @Component 
  2. public class GetSetAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         userDTO.setUserId(var.getUserId()); 
  8.         userDTO.setUserNickName(var.getUserNickName()); 
  9.         userDTO.setCreateTime(var.getCreateTime()); 
  10.         return userDTO; 
  11.     } 
  12.  
  • 推薦:★★★☆☆
  • 性能:★★★★★
  • 手段:手寫
  • 點評:其實這種方式也是日常使用的最多的,性能肯定是杠杠的,就是操作起來有點麻煩。尤其是一大堆屬性的 VO 對象轉換為 DTO 對象時候。但其實也有一些快捷的操作方式,比如你可以通過 Shift+Alt 選中所有屬性,Shift+Tab 歸并到一列,接下來在使用 Alt 選中這一列,批量操作粘貼 userDTO.set 以及快捷鍵大寫屬性首字母,最后切換到結尾補充括號和分號,最終格式化一下就搞定了。

2. json2Json

  1. @Component 
  2. public class Json2JsonAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         String strJson = JSON.toJSONString(var); 
  7.         return JSON.parseObject(strJson, UserDTO.class); 
  8.     } 
  9.  
  • 推薦:☆☆☆☆☆
  • 性能:★☆☆☆☆
  • 手段:把對象轉JSON串,再把JSON轉另外一個對象
  • 點評:這么寫多半有點燒!

3. Apache copyProperties

  1. @Component 
  2. public class ApacheCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         try { 
  8.             BeanUtils.copyProperties(userDTO, var); 
  9.         } catch (IllegalAccessException | InvocationTargetException e) { 
  10.             e.printStackTrace(); 
  11.         } 
  12.         return userDTO; 
  13.     } 
  14.  
  • 推薦:☆☆☆☆☆
  • 性能:★☆☆☆☆
  • 手段:Introspector 機制獲取到類的屬性來進行賦值操作
  • 點評:有坑,兼容性交差,不建議使用

4. Spring copyProperties

  1. @Component 
  2. public class SpringCopyPropertiesAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         BeanUtils.copyProperties(var, userDTO); 
  8.         return userDTO; 
  9.     } 
  10.  
  • 推薦:★★★☆☆
  • 性能:★★★★☆
  • 手段:Introspector機制獲取到類的屬性來進行賦值操作
  • 點評:同樣是反射的屬性拷貝,Spring 提供的 copyProperties 要比 Apache 好用的多,只要你不用錯,基本不會有啥問題。

5. Bean Mapping

  1. @Component 
  2. public class BeanMappingAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         BeanUtil.copyProperties(var, userDTO); 
  8.         return userDTO; 
  9.     } 
  10.  
  • 推薦:★★☆☆☆
  • 性能:★★★☆☆
  • 手段:屬性拷貝
  • 點評:性能一般

6. Bean Mapping ASM

  1. @Component 
  2. public class BeanMappingAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         BeanUtil.copyProperties(var, userDTO); 
  8.         return userDTO; 
  9.     } 
  10.  
  • 推薦:★★★☆☆
  • 性能:★★★★☆
  • 手段:基于ASM字節碼框架實現
  • 點評:與普通的 Bean Mapping 相比,性能有所提升,可以使用。

7. BeanCopier

  1. @Component 
  2. public class BeanCopierAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     @Override 
  5.     public UserDTO sourceToTarget(UserVO var) { 
  6.         UserDTO userDTO = new UserDTO(); 
  7.         BeanCopier beanCopier = BeanCopier.create(var.getClass(), userDTO.getClass(), false); 
  8.         beanCopier.copy(var, userDTO, null); 
  9.         return userDTO; 
  10.     } 
  11.  
  • 推薦:★★★☆☆
  • 性能:★★★★☆
  • 手段:基于CGlib字節碼操作生成get、set方法
  • 點評:整體性能很不錯,使用也不復雜,可以使用

8. Orika

  1. @Component 
  2. public class OrikaAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     /** 
  5.      * 構造一個MapperFactory 
  6.      */ 
  7.     private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 
  8.  
  9.     static { 
  10.         mapperFactory.classMap(UserDTO.class, UserVO.class) 
  11.                 .field("userId""userId")  // 字段不一致時可以指定 
  12.                 .byDefault() 
  13.                 .register(); 
  14.     } 
  15.  
  16.     @Override 
  17.     public UserDTO sourceToTarget(UserVO var) { 
  18.         return mapperFactory.getMapperFacade().map(var, UserDTO.class); 
  19.     } 
  20.  
  • 官網:https://orika-mapper.github.io/orika-docs/
  • 推薦:★★☆☆☆
  • 性能:★★★☆☆
  • 手段:基于字節碼生成映射對象
  • 點評:測試性能不是太突出,如果使用的話需要把 MapperFactory 的構建優化成 Bean 對象

9. Dozer

  1. @Component 
  2. public class DozerAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     private static DozerBeanMapper mapper = new DozerBeanMapper(); 
  5.  
  6.     @Override 
  7.     public UserDTO sourceToTarget(UserVO var) { 
  8.         return mapper.map(var, UserDTO.class); 
  9.     } 
  10.  
  • 官網:http://dozer.sourceforge.net/documentation/gettingstarted.html
  • 推薦:★☆☆☆☆
  • 性能:★★☆☆☆
  • 手段:屬性映射框架,遞歸的方式復制對象
  • 點評:性能有點差,不建議使用

10. ModelMapper

  1. @Component 
  2. public class ModelMapperAssembler implements IAssembler<UserVO, UserDTO> { 
  3.  
  4.     private static ModelMapper modelMapper = new ModelMapper(); 
  5.  
  6.     static { 
  7.         modelMapper.addMappings(new PropertyMap<UserVO, UserDTO>() { 
  8.             @Override 
  9.             protected void configure() { 
  10.                 // 屬性值不一樣可以自己操作 
  11.                 map().setUserId(source.getUserId()); 
  12.             } 
  13.         }); 
  14.     } 
  15.  
  16.     @Override 
  17.     public UserDTO sourceToTarget(UserVO var) { 
  18.         return modelMapper.map(var, UserDTO.class); 
  19.     } 
  20.  
  • 官網:http://modelmapper.org
  • 推薦:★★★☆☆
  • 性能:★★★☆☆
  • 手段:基于ASM字節碼實現
  • 點評:轉換對象數量較少時性能不錯,如果同時大批量轉換對象,性能有所下降

11. JMapper

  1. JMapper<UserDTO, UserVO> jMapper = new JMapper<>(UserDTO.class, UserVO.class, new JMapperAPI() 
  2.         .add(JMapperAPI.mappedClass(UserDTO.class) 
  3.                 .add(JMapperAPI.attribute("userId"
  4.                         .value("userId")) 
  5.                 .add(JMapperAPI.attribute("userNickName"
  6.                         .value("userNickName")) 
  7.                 .add(JMapperAPI.attribute("createTime"
  8.                         .value("createTime")) 
  9.         )); 
  • 官網:https://github.com/jmapper-framework/jmapper-core/wiki
  • 推薦:★★★★☆
  • 性能:★★★★★
  • 手段:Elegance, high performance and robustness all in one java bean mapper
  • 點評:速度真心可以,不過結合 SpringBoot 感覺有的一點點麻煩,可能姿勢不對

12. MapStruct

  1. @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedSourcePolicy = ReportingPolicy.IGNORE
  2. public interface UserDTOMapping extends IMapping<UserVO, UserDTO> { 
  3.  
  4.     /** 用于測試的單例 */ 
  5.     IMapping<UserVO, UserDTO> INSTANCE = Mappers.getMapper(UserDTOMapping.class); 
  6.  
  7.     @Mapping(target = "userId", source = "userId"
  8.     @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss"
  9.     @Override 
  10.     UserDTO sourceToTarget(UserVO var1); 
  11.  
  12.     @Mapping(target = "userId", source = "userId"
  13.     @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss"
  14.     @Override 
  15.     UserVO targetToSource(UserDTO var1); 
  16.  
  • 官網:https://github.com/mapstruct/mapstruct
  • 推薦:★★★★★
  • 性能:★★★★★
  • 手段:直接在編譯期生成對應的get、set,像手寫的代碼一樣
  • 點評:速度很快,不需要到運行期處理,結合到框架中使用方便

四、總結

其實對象屬性轉換的操作無非是基于反射、AOP、CGlib、ASM、Javassist 在編譯時和運行期進行處理,再有好的思路就是在編譯前生成出對應的get、set,就像手寫出來的一樣。

所以我更推薦我喜歡的 MapStruct,這貨用起來還是比較舒服的,一種是來自于功能上的拓展性,易用性和兼容性。

 

無論哪種使用,都要做一下完整的測試和驗證,不要上來就復制粘貼,否則你可能早早的就把挖好坑了,當然不一定是哪個兄弟來填坑了。

 

責任編輯:武曉燕 來源: bugstack蟲洞棧
相關推薦

2022-12-09 07:53:20

vo2dto方法AOP

2021-12-15 10:26:13

Docker代碼接口

2023-02-22 08:15:13

壓測模擬計算

2024-11-29 07:34:36

PO持久化對象

2022-09-13 08:40:51

DTOVOPO

2021-05-31 09:00:00

數據存儲存儲系統工具

2014-07-10 10:33:47

CoolHash引擎壓測

2022-11-25 18:49:11

云原生

2019-08-19 00:14:12

網絡測試帶寬網絡流量

2021-03-08 08:54:12

驅動模型DTODO

2010-06-07 09:11:43

jQuery

2024-10-16 17:01:17

Java開發SpringBoot

2014-03-06 09:52:23

數據備份恢復數據安全

2014-11-25 11:37:17

壓測 軟件測試

2016-08-08 18:11:50

服務器壓力測試

2019-12-31 14:21:00

數據挖掘關系網絡數據

2019-11-19 07:56:30

MySQL壓測數據表

2023-01-16 08:09:22

PulsarMQ

2022-01-17 09:18:28

JMeter分布式壓測

2010-11-03 11:36:53

訪問DB2表
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 特级毛片爽www免费版 | 在线亚洲欧美 | 国产精品婷婷 | 一区二区三区免费观看 | 久久久久亚洲国产| 欧美日韩不卡合集视频 | 亚洲精品日韩精品 | 国产一区2区 | 中文字幕不卡一区 | 亚洲精品久久久久久一区二区 | 国产在线激情视频 | 99久久精品免费看国产免费软件 | 亚洲国产精品99久久久久久久久 | 国产成人在线播放 | 欧美一级高潮片免费的 | 亚洲免费在线 | 日韩视频一级 | 久久人人爽人人爽人人片av免费 | 中文字幕一区二区三区不卡 | 伊人春色在线观看 | 亚洲经典一区 | 麻豆视频在线看 | 中文字幕在线欧美 | 天天操操 | 亚洲欧美日韩精品久久亚洲区 | 91亚洲精华国产 | 91麻豆蜜桃一区二区三区 | 精品国产青草久久久久福利 | 亚洲免费一区 | 正在播放国产精品 | 福利视频网站 | 99精品99| 亚洲精品视频在线观看免费 | 日韩欧美电影在线 | 欧美日韩1区 | 久久一久久| 国产激情视频在线观看 | 91免费电影 | 欧美日韩在线视频一区 | 亚洲欧美一区二区三区在线 | 久久久久久一区 |