日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java MapStruct解了對象映射的毒

瀏覽:94日期:2022-08-13 17:12:41
前言

MVC模式是目前主流項目的標準開發模式,這種模式下框架的分層結構清晰,主要分為Controller,Service,Dao。分層的結構下,各層之間的數據傳輸要求就會存在差異,我們不能用一個對象來貫穿3層,這樣不符合開發規范且不夠靈活。

我們常常會遇到層級之間字段格式需求不一致的情況,例如數據庫中某個字段是datetime日期格式,這個時間戳在數據庫中的存儲值為2020-11-06 23:59:59.999999,但是傳遞給前端的時候要求接口返回yyyy-MM-dd的格式,或者有些數據在數據庫中是逗號拼接的String類型,但是前端需要的是切割后的List類型等等。

所以我們提出了層級間的對象模型,就是我們常見的VO,DTO,DO,PO等等。這種區分層級對象模型的方式雖然清晰化了我們各層級間的對象傳遞,但是對象模型間的相互轉換和值拷貝確是讓人感覺很麻煩,拷貝來拷貝去,來來回回,過程重復乏味,編寫此類映射代碼是一項繁瑣且容易出錯的任務。

最簡單粗糙的拷貝方法就是不斷的new對象然后對象間的 setter 和 getter,這種方式應對字段屬性少的還可以,如果屬性字段很多那么大段的set,get的代碼就顯得很不雅美。因此需要借助對象拷貝工具,目前市場上的也蠻多的像BeanCopy,Dozer等等,但是這些我感覺都不夠好,今天我推薦一個實體映射工具就是 MapStruct。

介紹

MapStruct的官網地址是 https://mapstruct.org/MapStruct,是一個快速安全的bean 映射代碼生成器,只需要通過簡單的注解就可以實現對象間的屬性轉換,是一款 Apache LICENSE 2.0 授權的開源產品,Github的源碼地址是 https://github.com/mapstruct。

Java MapStruct解了對象映射的毒

通過官網的三連問(What,Why,How)我們可以大概的了解到 MapStruct 的作用,它的優勢以及它是如何實現的。

Java MapStruct解了對象映射的毒

從上面的三連問中我們可以得到如下信息:

基于約定優于配置的方法 MapStruct 極大地簡化了 Java bean 類型之間的映射的實現,通過簡單的注解就可以工作。生成的映射代碼使用普通的方法調用而不是反射,因此速度快,類型安全且易于理解。 在編譯時生成 Bean 映射 與其他映射框架相比,MapStruct 在編譯時生成 Bean 映射,這樣可以確保高性能,而且開發人員可以快速的得到反饋和徹底的錯誤檢查。 一個注釋處理器 MapStruct 是一個注釋處理器,已插入 Java 編譯器,可用于命令行構建(Maven,Gradle等),也可用于您首選的IDE中(IDEA,Eclipse等)。代碼編寫

MapStruct 需要 Java 1.8或更高版本。對于Maven-based 的項目,在pom 文件中添加如下依賴即可

<!-- 指定版本--><properties> <org.mapstruct.version>1.4.1.Final</org.mapstruct.version></properties><!-- 添加依賴 --><dependencies> <dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version> </dependency> <dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version> </dependency></dependencies>

基本的依賴引入后就可以編寫代碼了,簡單的定義一個映射類,為了與 Mybatis中的 mapper 接口區分,我們可以取名為 xxObjectConverter。

例如汽車對象的映射類名為 CarObjectConverter,我們有兩個對象模型 DO 和 DTO,它們內部的屬性字段如下:

數據庫對應的持久化對象模型 CarDo

public class Car { @ApiModelProperty(value = '主鍵id') private Long id; @ApiModelProperty(value = '制造商') private String manufacturers; @ApiModelProperty(value = '銷售渠道') private String saleChannel; @ApiModelProperty(value = '生產日期') private Date productionDate; ...}

層級間傳輸的對象模型 CarDto

public class CarDto { @ApiModelProperty(value = '主鍵id') private Long id; @ApiModelProperty(value = '制造商') private String maker; @ApiModelProperty(value = '銷售渠道') private List<Integer> saleChannel; @ApiModelProperty(value = '生產日期') private Date productionDate; ...}

再編寫具體的 MapStruct 對象映射器

@Mapperpublic interface CarObjectConverter{ CarObjectConverter INSTANCE = Mappers.getMapper(CarObjectConverter.class); @Mapping(target = 'maker', source = 'manufacturers') CarDto carToCarDto(Car car);}

對于字段名相同的可以不用額外的指定映射規則,但是字段名不同的屬性則需要指出字段的映射規則,如上我們持久層 DO 的制造商的字段名是manufacturers 而層級間傳輸的DTO模型中則是maker,我們就需要在映射方法上通過@Mapping注解指出映射規則,我個人習慣是喜歡將target寫在前面,source寫在后面,這樣是與映射對象的位置保持一致,差異字段多的時候方便對比且不易混淆。

開發過程中還會經常遇到一些日期格式的轉換,就如開篇時說的那種,這時我們也可以指定日期的映射規則

@Mapperpublic interface CarObjectConverter{ CarObjectConverter INSTANCE = Mappers.getMapper(CarObjectConverter.class); @Mapping(target = 'maker', source = 'manufacturers') @Mapping(target = 'productionDate', dateFormat = 'yyyy-MM-dd', source = 'productionDate') CarDto carToCarDto(Car car);}

這些都還是一些簡單的字段的映射,但有時候我們兩個對象模型間的字段類型不一致,如上汽車的銷售渠道字段saleChannel,這個在數據庫中是字符串逗號拼接的值1,2,3,而我們傳遞出去的需要是 List 的 Integer 類型,這種復雜的如何映射呢?

也是有方法的,我們先編寫一個將字符串逗號分隔然后轉成 List 的工具方法,如下

public class CollectionUtils { public static List<Integer> list2String(String str) {if (StringUtils.isNoneBlank(str)) { return Arrays.asList(str.split(',')).stream().map(s -> Integer.valueOf(s.trim())).collect(Collectors.toList());}return null; }}

然后在映射Mapping中使用表達式即可

@Mapperpublic interface CarObjectConverter { CarObjectConverter INSTANCE = Mappers.getMapper(CarObjectConverter.class); @Mapping(target = 'maker', source = 'manufacturers') @Mapping(target = 'productionDate', dateFormat = 'yyyy-MM-dd', source = 'productionDate') @Mapping(target = 'saleChannel', expression = 'java(com.jiajian.demo.utils.CollectionUtils.list2String(car.getSaleChannel()))') CarDto carToCarDto(Car car);}

這樣就完成了所有字段的映射工作,我們在需要對象模型轉換的地方按照如下方式調用即可

CarDto carDto = CarObjectConverter.INSTANCE.carToCarDto(car);

這種是單體對象之間的 Copy 很多時候我們需要 List 對象模型間的轉換,只需要再寫一個方法carToCarDtos即可

@Mapperpublic interface CarObjectConverter{ CarObjectConverter INSTANCE = Mappers.getMapper(CarObjectConverter.class); @Mapping(target = 'maker', source = 'manufacturers') @Mapping(target = 'productionDate', dateFormat = 'yyyy-MM-dd', source = 'productionDate') @Mapping(target ='saleChannel', expression = 'java(com.jiajian.demo.utils.CollectionUtils.list2String(car.getSaleChannel()))') CarDto carToCarDto(Car car); List<CarDto> carToCarDtos(List<Car> carList);}探個究竟

會不會好奇這是怎么實現的,我們只是創建了一個接口然后在接口方法上加一個注解并在注解里面指定字段的映射規則就可以實現對象屬性間的拷貝,這是怎么做到的呢?

我們這里通過 MapStruct 創建的只是一個接口,要實現具體的功能接口必有實現。

MapStruct 會在我們代碼編譯的時候為我們創建一個實現類,而這個實現類里面通過字段的setter, getter方法來實現字段的賦值,從而實現對象的映射。

Java MapStruct解了對象映射的毒

這里需要注意一點:如果你修改了任一映射對象,記得需要先執行mvn clean再啟動項目,否則調試的時候會報錯。

結尾

MapStrut 的功能遠不至于上面介紹的這些,我只是挑出幾個常用的語法進行示例講解,如果讀者感興趣想深入的了解更多可以參考官方的參考文檔

遇見 MapStruct 后我就開始在項目中拋棄掉了原來的那些 BeanCopyUtils 的工具,相對而言 MapStruct 確實更簡潔且易使用而且定制功能也很強。

從編譯文件可以看出 MapStruct 是通過setter,getter來實現屬性值的拷貝,然后這種方式不是最簡單又最安全高效的嗎?只是 MapStruct 更好的幫助我們實現了,避免了項目中冗余的重復代碼,大道至簡。

以上就是MapStruct解了對象映射的毒的詳細內容,更多關于MapStruct的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
黄色aa久久| 免费黄色成人| 亚洲综合二区| 91久久中文| 午夜日韩av| 亚洲黄色在线| 99国产精品一区二区| 日韩国产一区| 99精品在线观看| 欧美女激情福利| 美国三级日本三级久久99| 日本亚洲视频在线| 国产精品一区二区三区美女 | 久久亚洲人体| 国产精品成人**免费视频| 久久精品系列| 一区二区亚洲精品| 天堂久久av| 日韩大片在线播放| 黄色日韩精品| 国产精品丝袜在线播放| 精品亚洲精品| 在线亚洲观看| 久久精品二区亚洲w码| 黄毛片在线观看| 免费人成黄页网站在线一区二区| 欧美永久精品| 精品黄色一级片| 国产精品91一区二区三区| 日韩国产高清在线| 欧美激情网址| 日韩在线观看一区二区| 国产毛片精品| 国产亚洲亚洲| 日韩欧美午夜| 91精品尤物| 国产 日韩 欧美 综合 一区| 亚洲一二av| 美女久久久久| 久久女人天堂| 欧美伊人久久| 一区二区日韩免费看| 成人在线免费观看91| 日韩va亚洲va欧美va久久| 日韩成人综合| 国产网站在线| 伊人久久亚洲热| 国产精品s色| 国产91在线精品| 欧美在线91| 热久久久久久久| 日本久久成人网| 成人精品国产亚洲| 婷婷精品久久久久久久久久不卡| 国产福利亚洲| 欧美一区=区| 久久在线免费| 99久久夜色精品国产亚洲狼| 国产一区二区三区四区五区| 精品伊人久久| 国产精品xx| 日韩免费在线| 亚洲视频综合| 欧美在线影院| 日韩精品视频网站| 久久国产免费看| 97久久亚洲| 国产欧美日韩综合一区在线播放| 国产精品三级| 国产一区二区三区四区二区| 日韩免费视频| 99日韩精品| 欧美一级网站| 免费在线小视频| 性欧美长视频| 国产精品宾馆| 午夜av成人| 中文字幕日韩高清在线| 久久国产乱子精品免费女| 国产一区三区在线播放| 91精品精品| 欧美日韩视频| 日韩高清电影免费| 久久久久免费| 亚洲影院天堂中文av色| 久久不卡国产精品一区二区| 九九精品调教| 日本不卡一区二区三区| 国产在线视频欧美一区| 日本 国产 欧美色综合| 国产h片在线观看| 在线观看亚洲精品福利片| 久久精品一本| 麻豆9191精品国产| 中文字幕人成乱码在线观看 | 久久久777| 日本不卡不码高清免费观看 | 欧美天堂一区二区| 日韩视频中文| 超碰超碰人人人人精品| 日韩区欧美区| 黄色日韩在线| 韩国三级一区| 国产精品高清一区二区| 日本欧美在线看| 国产乱码午夜在线视频| 欧美亚洲网站| 美女网站久久| 精品中文一区| 亚洲精品福利电影| 欧美亚洲一区二区三区| 亚洲尤物av| 不卡中文一二三区| 午夜精品久久久久久久久久蜜桃| 久久99偷拍| 色综合视频一区二区三区日韩 | 久久精品欧美一区| 欧美精品99| 日本午夜精品视频在线观看| 亚洲综合二区| 久久亚洲色图| 老牛影视一区二区三区| 婷婷综合亚洲| 亚洲成人一区| 午夜精品亚洲| 日韩在线一区二区| 日韩在线一二三区| 亚洲区国产区| 日韩动漫一区| 欧美激情视频一区二区三区在线播放| 日本一区二区三区视频在线看| 午夜av成人| 欧美精品一线| 亚洲三区欧美一区国产二区| 天使萌一区二区三区免费观看| 99xxxx成人网| 日韩精品第二页| 欧美a级一区二区| 精品国产乱码久久久| 日韩成人精品一区二区| 久久九九99| 每日更新成人在线视频| 婷婷精品久久久久久久久久不卡| 日本精品一区二区三区在线观看视频| 国产日韩一区二区三区在线播放| 久久只有精品| 成人日韩av| 亚洲精品99| 国产探花一区在线观看| 五月激情久久| 日韩高清一级| 涩涩av在线| 中文字幕日韩亚洲| 欧美a在线观看| 女人天堂亚洲aⅴ在线观看| 在线精品福利| 福利在线免费视频| 最新国产精品视频| sm久久捆绑调教精品一区| 日本大胆欧美人术艺术动态| 老司机免费视频一区二区三区| 欧美国产极品| 免费观看久久久4p| 91综合网人人| 国产情侣一区在线| 99热精品在线| 韩国久久久久久| 国产欧美69| 三级欧美韩日大片在线看| www在线观看黄色| 国产乱码精品一区二区三区四区 | 国产黄大片在线观看| 亚洲精品女人| 久久国产亚洲精品| 69堂精品视频在线播放| 欧美理论视频| 久久精品国产福利| 国产亚洲欧美日韩精品一区二区三区 | 久久精品国产www456c0m| 欧美日韩网址| 午夜在线播放视频欧美| 伊人久久亚洲热| 国产欧美一区二区色老头| 欧美日韩国产欧| 日韩中文在线电影| 久久99久久人婷婷精品综合| 亚洲字幕久久| 蜜桃av一区二区在线观看| 国产一区二区三区探花| 免费精品一区| 麻豆精品视频在线| 欧美日韩一区二区三区四区在线观看 | 欧美亚洲在线日韩| 久久久国产精品一区二区中文| 久久精品天堂| 国模大尺度视频一区二区| 国产精品亚洲综合久久| 国产亚洲精品美女久久 | 日本欧美国产| 国产女人18毛片水真多18精品|