0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MapStruct中的高級特性使用

jf_ro2CN3Fa ? 來源:芋道源碼 ? 2023-05-26 15:59 ? 次閱讀

事件回顧

分析探討

推薦方案

總結(jié)

44ca47fa-fafb-11ed-90ce-dac502259ad0.jpg

前言

最近項目上要求升級一個工具包hutool的版本,以解決安全漏洞問題,這不升級還好,一升級反而捅出了更大的簍子,究竟是怎么回事呢?

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://github.com/YunaiV/ruoyi-vue-pro

視頻教程:https://doc.iocoder.cn/video/

事件回顧

我們項目原先使用的hutool版本是5.7.2,在代碼中,我們的數(shù)據(jù)傳輸對象DTO和數(shù)據(jù)實體對象中大量使用了工具包中的BeanUtil.copyProperties(), 大體代碼如下:

數(shù)據(jù)傳輸對象

@Data
@ToString
publicclassDiagramDTO{

//前端生產(chǎn)的字符串id
privateStringid;

privateStringcode;

privateStringname;
}

數(shù)據(jù)實體對象

@Data
@ToString
publicclassDiagram{

privateIntegerid;

privateStringcode;

privateStringname;
}

業(yè)務(wù)邏輯

publicclassBeanCopyTest{

publicstaticvoidmain(String[]args){
//前端傳輸?shù)膶ο?DiagramDTOdiagramDTO=newDiagramDTO();
//如果前端傳入的id事包含e的,升級后就會報錯
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("圖表");

Diagramdiagram=newDiagram();
//關(guān)鍵點,數(shù)據(jù)拷貝
BeanUtil.copyProperties(diagramDTO,diagram);
System.out.println("數(shù)據(jù)實體對象:"+diagram);
//設(shè)置id為空,自增
diagram.setId(null);
//保存到數(shù)據(jù)庫中TODO
//diagramMapper.save(diagram);
}
}

升級前,hutool是5.7.2版本下,執(zhí)行結(jié)果如下圖。

44d670de-fafb-11ed-90ce-dac502259ad0.png

BeanUtil.copyProperties雖然字段類型不一樣,但是做了兼容處理,所以業(yè)務(wù)沒有影響業(yè)務(wù)邏輯。

升級后,hutool是5.8.8版本,執(zhí)行結(jié)果如下圖所示:

44e28d92-fafb-11ed-90ce-dac502259ad0.png

執(zhí)行報錯,因為升級后的版本修改了實現(xiàn),增加了下面的邏輯,如果包含E, 就會拋錯,從而影響了業(yè)務(wù)邏輯,同時這個id是否包含e又是隨機因素,到了生產(chǎn)才發(fā)現(xiàn),就悲劇了。

44f0d21c-fafb-11ed-90ce-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://github.com/YunaiV/yudao-cloud

視頻教程:https://doc.iocoder.cn/video/

分析探討

我發(fā)現(xiàn)大部分人寫代碼都喜歡偷懶,在上面的場景中,雖然BeanUtil.copyProperties用的一時爽,但有時候帶來的后果是很嚴重的,所以很不推薦這種方式。為什么這么說呢?

比如團隊中的某些人偷偷改了數(shù)據(jù)傳輸對象DTO,比如修改了類型、刪去了某個字段。用BeanUtil.copyProperties的方式壓根無法在編譯階段發(fā)現(xiàn),更別提修改的影響范圍了,這就只能把風險暴露到生產(chǎn)上去了。那有什么更好的方法呢?

推薦方案

原始的get、set方式

我是比較推崇這種做法的,比如現(xiàn)在DiagramDTO刪去某個字段,編譯器就會報錯,就會引起你的注意了,讓問題提前暴露,無處遁形。

44fc19ba-fafb-11ed-90ce-dac502259ad0.png

你可能覺得站著說話不腰疼,字段少好,如果字段很多還不得寫死啊,我這里推薦一個IDEA的插件,可以幫你智能生成這樣的代碼。

450bdb98-fafb-11ed-90ce-dac502259ad0.png45126594-fafb-11ed-90ce-dac502259ad0.png

話不多說,自己玩兒去~~

使用開源庫ModelMapper

ModelMapper是一個開源庫,可以很方便、簡單地將對象從一種類型映射到另一種類型,底層是通過反射來自動確定對象之間的映射,還可以自定義映射規(guī)則。

privatestaticvoidtestModelMapper(){
ModelMappermodelMapper=newModelMapper();
DiagramDTOdiagramDTO=newDiagramDTO();
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("圖表");
Diagramdiagram=modelMapper.map(diagramDTO,Diagram.class);
}

使用開源庫MapStruct

MapStruct也是Java中另外一個用于映射對象很流行的開源工具。它是在編譯階段生成對應(yīng)的映射代碼,相對于ModelMapper底層放射的方案,性能更好。

@Mapper
publicinterfaceDiagramMapper{
DiagramMapperINSTANCE=Mappers.getMapper(DiagramMapper.class);

DiagramDTOtoDTO(Diagramdiagram);

DiagramtoEntity(DiagramDTOdiagram);
}

privatestaticvoidtestMapStruct(){
DiagramDTOdiagramDTO=newDiagramDTO();
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("圖表");
Diagramdiagram=DiagramMapper.INSTANCE.toEntity(diagramDTO);
}

DiagramMapper接口使用了@Mapper注解,用來表明使用MapStruct處理

MapStruct中更多高級特性大家自己探索一下。

總結(jié)

小結(jié)一下,對象在不同層之間進行轉(zhuǎn)換映射,很不建議使用BeanUtil.copyProperties這種方式,更加推薦使用原生的set, get方式,不容易出錯。當然這不是將BeanUtil.copyProperties一棒子打死,毫無用武之地,在特定場景,比如方法內(nèi)部對象的轉(zhuǎn)換等影響小的范圍還是很方便的。

審核編輯:彭靜
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67767
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    646

    瀏覽量

    32671

原文標題:麻了!不要再動不動就用BeanUtil.copyProperties了?。?/p>

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Python高級特性:迭代器切片的應(yīng)用

    是 Python 獨特的一種高級特性,而切片也是一種高級特性,兩者相結(jié)合,會產(chǎn)生什么樣的結(jié)果呢? 1、迭代與迭代器 首先,有幾個基本概念要
    發(fā)表于 11-29 10:11 ?627次閱讀

    對象轉(zhuǎn)換工具:MapStruct

    在我們?nèi)粘i_發(fā)的程序,為了各層之間解耦,一般會定義不同的對象用來在不同層之間傳遞數(shù)據(jù),比如xxxDTO、xxxVO、xxxQO,當在不同層之間傳輸數(shù)據(jù)時,不可避免地經(jīng)常需要將這些對象進行
    的頭像 發(fā)表于 10-08 14:39 ?910次閱讀

    16位高級控制定時器STM816有哪些特性?

    STM816位高級控制定時器的主要特性
    發(fā)表于 11-16 07:23

    高級處理器特性能否提高編碼效率?

    高級處理器特性能否提高編碼效率?
    發(fā)表于 04-26 06:41

    高級控制定時器有哪些特性

    高級控制定時器和通用定時器有何功能?高級控制定時器有哪些特性呢?
    發(fā)表于 11-10 06:51

    LabVIEW調(diào)用DLL的高級技巧后續(xù)資源包

    1、LabVIEW調(diào)用DLL的高級技巧2、.NET InteropAssembly Builder3、LabVIEW機器人版
    發(fā)表于 07-01 08:28 ?209次下載

    Trace32的高級功能特性

    Trace32的高級功能特性 Logic analyzer Real-time Streaming and Profiling Boundary Scan Third Party Tools Intergrations Virtual Targets Debugging
    發(fā)表于 11-16 12:52 ?28次下載
    Trace32的<b class='flag-5'>高級</b>功能<b class='flag-5'>特性</b>

    關(guān)于 FPGA 高級 IO 時序

    高級 IO 時序
    的頭像 發(fā)表于 06-22 05:05 ?3159次閱讀
    關(guān)于 FPGA <b class='flag-5'>中</b>的<b class='flag-5'>高級</b> IO 時序

    在設(shè)計如何使用高級PCB模塊

    添加高級 PCB 模塊可以使 PADS Standard Plus 的功能更加強大。此模塊物超所值,其中包含了高速自動布線、DFT 審核和高級封裝功能。在此視頻,我們將向您展示如何使用高級
    的頭像 發(fā)表于 05-14 06:21 ?1973次閱讀

    STMCube.AI的高級特性

    STM32CubeMX的功能。它還提供幾種在桌面PC和STM32上驗證神經(jīng)網(wǎng)絡(luò)模型以及測量模型性能的方法,而無需用戶手工編寫專門的C語言代碼。 上一篇文章大致介紹了STMCube.AI的基本特性,以及其工作流程。 本文將更深入地介紹它的一些高級
    的頭像 發(fā)表于 10-28 10:05 ?1892次閱讀
    STMCube.AI的<b class='flag-5'>高級</b><b class='flag-5'>特性</b>

    STM32Cube.AI庫的高級特性

    STM32CubeMX的功能。它還提供幾種在桌面PC和STM32上驗證神經(jīng)網(wǎng)絡(luò)模型以及測量模型性能的方法,而無需用戶手工編寫專門的C語言代碼。 上一篇文章大致介紹了STMCube.AI的基本特性,以及其工作流程。 本文將更深入地介紹它的一些高級
    的頭像 發(fā)表于 11-16 16:59 ?2975次閱讀
    STM32Cube.AI庫的<b class='flag-5'>高級</b><b class='flag-5'>特性</b>

    SOK將HugeCTR高級特性進行包裝使用

    ),來將 HugeCTR 高級特性封裝為 TensorFlow 可直接調(diào)用的形式,從而幫助用戶在 TensorFlow 中直接使用 HugeCTR
    的頭像 發(fā)表于 04-07 16:02 ?1173次閱讀
    SOK將HugeCTR<b class='flag-5'>中</b>的<b class='flag-5'>高級</b><b class='flag-5'>特性</b>進行包裝使用

    英特爾高級鏈路分析器全新混合行為模式,兼“雙優(yōu)”特性

    英特爾 Quartus Prime 設(shè)計軟件的英特爾 高級鏈路分析器擁有全新特性。它除了支持英特爾 Stratix 10 TX 家族 E-Tile IBIS-AMI,提供封裝支持,還擁有全新的通道查看器功能。
    發(fā)表于 01-31 14:44 ?248次閱讀

    別再用BeanUtils了,這款PO VO DTO轉(zhuǎn)換神器不香么?

    關(guān)于lombok和mapstruct的版本兼容問題多說幾句,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外編譯的lombok mapstruct的插件不要忘了加上。
    的頭像 發(fā)表于 07-10 10:46 ?465次閱讀
    別再用BeanUtils了,這款PO VO DTO轉(zhuǎn)換神器不香么?

    如何在實際的代碼中使Spring組件的特性

    首先,我們將探討一些 Spring 框架 IOC(Inversion of Control)的高級特性,特別是組件掃描的相關(guān)知識。
    的頭像 發(fā)表于 08-11 09:52 ?495次閱讀
    如何在實際的代碼中使Spring組件的<b class='flag-5'>特性</b>?