Java中MapStruct入門(mén)使用及對(duì)比
一.簡(jiǎn)單介紹
1.什么是 MapStruct?
MapStruct 是一個(gè) Java 注解處理器框架,用于簡(jiǎn)化 Java Bean 之間的映射。它通過(guò)生成映射代碼來(lái)消除手動(dòng)編寫(xiě)映射代碼的繁瑣工作,從而提高開(kāi)發(fā)效率。
2.MapStruct 的特點(diǎn)
- 簡(jiǎn)化映射: MapStruct 旨在簡(jiǎn)化 Java Bean 之間的映射,減少手動(dòng)編寫(xiě)映射代碼的工作量。
- 注解處理器: MapStruct 使用注解處理器技術(shù),在編譯時(shí)生成映射代碼,而不是在運(yùn)行時(shí)進(jìn)行反射。
- 類型安全: 通過(guò)在映射接口上使用注解,MapStruct 能夠在編譯時(shí)檢查映射的正確性,提供類型安全性。
- 支持自定義映射邏輯: 盡管 MapStruct 提供了默認(rèn)的映射規(guī)則,但你仍然可以通過(guò)在映射接口中定義自定義方法來(lái)指定特定的映射邏輯。
二.基礎(chǔ)使用
1.添加依賴
添加依賴: 首先,在你的項(xiàng)目中添加 MapStruct 的依賴。你可以在 Maven 或 Gradle 中進(jìn)行配置。
Maven:
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.4.2.Final</version> <!-- 使用最新版本 --> </dependency>
Gradle:
implementation 'org.mapstruct:mapstruct:1.4.2.Final' // 使用最新版本 annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
2.定義映射接口
定義映射接口: 創(chuàng)建一個(gè)帶有@Mapper
注解的接口,定義映射方法。
@Mapper public interface CarMapper { CarDto carToCarDto(Car car); }
3.編寫(xiě)配置
編寫(xiě)映射配置: 如果需要自定義映射邏輯,可以在映射接口中定義自定義方法,或者使用@Mapping
注解。
@Mapper public interface CarMapper { @Mapping(source = "make", target = "manufacturer") CarDto carToCarDto(Car car); }
4.生成代碼
生成映射代碼: 編譯項(xiàng)目時(shí),MapStruct 注解處理器將生成映射代碼。
5.調(diào)用方法
調(diào)用映射方法: 在應(yīng)用程序中調(diào)用生成的映射方法。
CarMapper carMapper = Mappers.getMapper(CarMapper.class); CarDto carDto = carMapper.carToCarDto(car);
以上是 MapStruct 的基本介紹和使用步驟。通過(guò)這些步驟,你可以輕松地實(shí)現(xiàn) Java Bean 之間的映射,同時(shí)保持代碼的簡(jiǎn)潔和易維護(hù)性。
三.封裝使用
1.FromConverter
public interface FromConverter<T, FROM> { T from(FROM from); List<T> from(List<FROM> list); default PageBean<T> from(PageBean<FROM> page) { PageBean<T> result = new PageBean<>(); result.setTotalElements(page.getTotalElements()); result.setNumber(page.getNumber()); result.setSize(page.getSize()); result.setTotalPages(page.getTotalPages()); result.setNumberOfElements(page.getNumberOfElements()); result.setContent(this.from(page.getContent())); return result; } default PageBean<T> from(IPage<FROM> page) { PageBean<T> result = new PageBean<>(); result.setTotalElements((int) page.getTotal()); result.setNumber((int) page.getCurrent()); result.setSize((int) page.getSize()); result.setTotalPages((int) page.getPages()); result.setNumberOfElements(page.getRecords().size()); result.setContent(this.from(page.getRecords())); return result; } }
2.PropertyCopier
public interface PropertyCopier<TARGET, T> { void copy(@MappingTarget TARGET target, T t); }
3.ToConverter
public interface ToConverter<T, TO> { TO to(T t); List<TO> to(List<T> list); default PageBean<TO> to(PageBean<T> page) { PageBean<TO> result = new PageBean<>(); result.setTotalElements(page.getTotalElements()); result.setNumber(page.getNumber()); result.setSize(page.getSize()); result.setTotalPages(page.getTotalPages()); result.setNumberOfElements(page.getNumberOfElements()); result.setContent(this.to(page.getContent())); return result; } default PageBean<TO> to(IPage<T> page) { PageBean<TO> result = new PageBean<>(); result.setTotalElements((int) page.getTotal()); result.setNumber((int) page.getCurrent()); result.setSize((int) page.getSize()); result.setTotalPages((int) page.getPages()); result.setNumberOfElements(page.getRecords().size()); result.setContent(this.to(page.getRecords())); return result; } }
4.TwoWayConverter
public interface TwoWayConverter<SRC, DEST> extends ToConverter<SRC, DEST>, FromConverter<SRC, DEST> { }
5.基本使用
@Data public class ChatbotDTO { private Integer id; private String question; private String response; private Date createTime; private Integer isDelete; @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface Converter extends FromConverter<ChatbotDTO, Chatbot> { Converter INSTANCE = Mappers.getMapper(Converter.class); } }
@Data public class Chatbot extends Model<Chatbot> { private Integer id; private String question; private String response; private Date createTime; private Integer isDelete; }
6.原理分析
打開(kāi) target 目錄,可以看到如圖所示的編譯后生成的類,說(shuō)明在編譯器就生成了對(duì)應(yīng)的 DTO,相比其他 2 種方式在運(yùn)行時(shí)生成 DTO 更加高效。
7.使用技巧
- 忽略字段映射
- 源對(duì)象與目標(biāo)對(duì)象屬性名不符的映射方法
- 直接設(shè)置特定值
- 表達(dá)式映射
- 自定義映射
四.工具對(duì)比
1.概述
MapStruct、Apache BeanUtils 以及 Spring BeanUtils 都是用于 Java Bean 之間屬性復(fù)制的工具,但它們有一些區(qū)別,包括實(shí)現(xiàn)方式、性能、功能等方面。
2.MapStruct
優(yōu)勢(shì):
- 編譯時(shí)檢查: MapStruct 在編譯時(shí)生成映射代碼,提供了類型安全性,可以在編譯時(shí)捕獲一些映射錯(cuò)誤。
- 性能: 由于生成的映射代碼是直接的 Java 代碼,MapStruct 通常在性能上優(yōu)于運(yùn)行時(shí)反射的解決方案。
- 可配置性: 提供了很高的自定義能力,你可以在映射接口中定義自定義方法或使用
@Mapping
注解來(lái)指定映射規(guī)則。 - MapStruct 能自動(dòng)的將名字一樣,類型不一致的屬性值進(jìn)行轉(zhuǎn)化再賦值(僅限基本類型的包裝類型,如果轉(zhuǎn)化值適配不了對(duì)應(yīng)類型會(huì)報(bào)錯(cuò))
不足:
- 學(xué)習(xí)曲線: 對(duì)于初學(xué)者而言,可能需要一些時(shí)間來(lái)理解和配置 MapStruct。
3.Apache BeanUtils
優(yōu)勢(shì):
- 簡(jiǎn)單易用: Apache BeanUtils 提供了簡(jiǎn)單的 API,易于上手。
- 反射: 使用反射機(jī)制實(shí)現(xiàn)屬性復(fù)制,可以在運(yùn)行時(shí)處理動(dòng)態(tài)對(duì)象。
不足:
- 性能: 相對(duì)于 MapStruct,Apache BeanUtils 在性能上可能較慢,因?yàn)樗褂梅瓷溥M(jìn)行屬性復(fù)制。
- 類型安全: 由于是在運(yùn)行時(shí)進(jìn)行反射,缺乏編譯時(shí)類型檢查。
4.Spring BeanUtils
優(yōu)勢(shì):
- 集成 Spring: Spring BeanUtils 是 Spring 框架的一部分,可以很容易地集成到 Spring 應(yīng)用程序中。
- 簡(jiǎn)化代碼: 提供了一些方便的方法,可以簡(jiǎn)化屬性復(fù)制的代碼。
不足:
- 性能: 與 Apache BeanUtils 類似,Spring BeanUtils 也是使用反射,因此性能相對(duì)較低。
- 可配置性: 相較于 MapStruct,可配置性相對(duì)較低。
5.總結(jié):
MapStruct 提供了編譯時(shí)類型檢查和高度可配置性,適用于需要更高性能和更復(fù)雜映射規(guī)則的場(chǎng)景。
Apache BeanUtils 和 Spring BeanUtils 簡(jiǎn)單易用,適用于簡(jiǎn)單的屬性復(fù)制場(chǎng)景,但在性能和類型安全性方面可能相對(duì)較差。
選擇使用哪個(gè)工具取決于你的具體需求,如果性能和類型安全性是關(guān)鍵考慮因素,而且你愿意付出一些學(xué)習(xí)成本,那么 MapStruct 可能是一個(gè)更好的選擇。如果你需要一個(gè)簡(jiǎn)單且易于使用的解決方案,并且性能要求不是很高,那么 Apache BeanUtils 或 Spring BeanUtils 可能是更合適的選擇。
到此這篇關(guān)于Java中MapStruct入門(mén)使用及對(duì)比的文章就介紹到這了,更多相關(guān)Java MapStruct內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中MapStruct的使用詳解
- Java中MapStruct使用方法解析
- Java中的MapStruct知識(shí)點(diǎn)總結(jié)
- Java中的MapStruct的使用方法代碼實(shí)例
- Java中的MapStruct實(shí)現(xiàn)詳解
- Java高效映射工具M(jìn)apStruct的使用示例
- Java中MapStruct映射處理器報(bào)錯(cuò)的問(wèn)題解決
- Java高性能實(shí)體類轉(zhuǎn)換工具M(jìn)apStruct的使用教程詳解
- SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制
- SpringBoot使用MapStruct生成映射代碼的示例詳解
- MapStruct升級(jí)遇到的問(wèn)題及解決方案
相關(guān)文章
SpringBoot+kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何結(jié)合kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下2024-01-01詳解如何在Spring Boot啟動(dòng)后執(zhí)行指定代碼
這篇文章主要介紹了在Spring Boot啟動(dòng)后執(zhí)行指定代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06java springboot郵箱找回密碼功能的實(shí)現(xiàn)講解
這篇文章主要介紹了java springboot郵箱找回密碼功能的實(shí)現(xiàn)講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01擴(kuò)展Hibernate使用自定義數(shù)據(jù)庫(kù)連接池的方法
這篇文章主要介紹了擴(kuò)展Hibernate使用自定義數(shù)據(jù)庫(kù)連接池的方法,涉及Hibernate數(shù)據(jù)庫(kù)操作擴(kuò)展的相關(guān)技巧,需要的朋友可以參考下2016-03-03Java實(shí)現(xiàn)ZooKeeper的zNode監(jiān)控
這篇文章主要介紹了Java實(shí)現(xiàn)ZooKeeper的zNode監(jiān)控問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-08-08Java格式化輸出詳細(xì)講解(printf、print、println、format等)
Java的格式化輸出等同于String.Format,與C有很大的相似,下面這篇文章主要給大家介紹了關(guān)于Java格式化輸出(printf、print、println、format等)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Spring MVC中處理ajax請(qǐng)求的跨域問(wèn)題與注意事項(xiàng)詳解
跨域問(wèn)題是我們大家在開(kāi)發(fā)中會(huì)經(jīng)常遇到的一個(gè)問(wèn)題,所以下面這篇文章主要給大家介紹了關(guān)于Spring MVC中處理ajax請(qǐng)求的跨域問(wèn)題與注意事項(xiàng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11