Java中的MapStruct的使用方法代碼實(shí)例
一、MapStruct 簡介
mapstruct是一種實(shí)體類映射框架,能夠通過Java注解將一個實(shí)體類的屬性安全地賦值給另一個實(shí)體類。有了mapstruct,只需要定義一個映射器接口,聲明需要映射的方法,在編譯過程中,mapstruct會自動生成該接口的實(shí)現(xiàn)類,實(shí)現(xiàn)將源對象映射到目標(biāo)對象的效果。
二、MapStruct 使用
切記:使用過程中遇到問題一定要看下面的必坑指南
1.引入依賴
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
這個依賴項(xiàng)會導(dǎo)入MapStruct的核心注釋。由于MapStruct在編譯時工作,并且會集成到像Maven和Gradle這樣的構(gòu)建工具上,我們還必須在<build中/>標(biāo)簽中添加一個插件maven-compiler-plugin,并在其配置中添加annotationProcessorPaths,該插件會在構(gòu)建時生成對應(yīng)的代碼。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--以下為mapstruct所需配置-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2. 基本映射
1.相同字段間映射
我們先從一些基本的映射開始。我們會創(chuàng)建一個UserInfo 對象和一個UserInfoDTO 對象,為了方便起見,它們的屬性字段都使用相同的名稱。
@Data
@TableName(value = "user_info")
public class UserInfo {
private String id;
private String name;
private String sex;
private String email;
}
@Data
public class UserInfoDTO {
private String id;
private String name;
private String sex;
private String email;
}現(xiàn)在,為了在這兩者之間進(jìn)行映射,我們要創(chuàng)建一個UserInfoConvert接口。對該接口使用@Mapper注解,MapStruct就會知道這是兩個類之間的映射器。
@Mapper
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
UserInfoDTO toDTO(UserInfo userInfo);
}這段代碼中創(chuàng)建了一個UserInfoConvert類型的實(shí)例INSTANCE,在生成對應(yīng)的實(shí)現(xiàn)代碼后,這就是我們調(diào)用的“入口”。
我們在接口中定義了toDTO()方法,該方法接收一個UserInfo實(shí)例為參數(shù),并返回一個UserInfoDTO實(shí)例。這足以讓MapStruct知道我們想把一個UserInfo 實(shí)例映射到一個UserInfoDTO實(shí)例。
當(dāng)我們構(gòu)建/編譯應(yīng)用程序時,MapStruct注解處理器插件會識別UserInfoConvert接口并為其生成一個實(shí)現(xiàn)類。
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-07-19T14:15:05+0800",
comments = "version: 1.5.2.Final, compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)
public class UserInfoConvertImpl implements UserInfoConvert {
@Override
public UserInfoDTO toDTO(UserInfo userInfo) {
if ( userInfo == null ) {
return null;
}
UserInfoDTO userInfoDTO = new UserInfoDTO();
return userInfoDTO;
}
}UserInfoConvertImpl 類中包含一個toDTO()方法,將我們的UserInfo 屬性值映射到userInfoDTO 的屬性字段中。如果要將UserInfo 實(shí)例映射到一個userInfoDTO 實(shí)例,可以這樣寫:
UserInfoDTO userInfoDTO = UserInfoConvert.INSTANCE.toDTO(userInfo);
2.不同字段間映射
通常,模型和DTO的字段名不會完全相同。由于團(tuán)隊(duì)成員各自指定命名,以及針對不同的調(diào)用服務(wù),開發(fā)者對返回信息的打包方式選擇不同,名稱可能會有輕微的變化。
注意下面兩個實(shí)體中的email字段不一致
public class UserInfo {
private String id;
private String name;
private String sex;
private String email;
}
@Data
public class UserInfoDTO {
private String id;
private String name;
private String sex;
private String myEmail;
}現(xiàn)在,我們需要讓 UserMapper 知道這里的不一致。我們可以使用 @Mapping 注解,并設(shè)置其內(nèi)部的 source 和 target 標(biāo)記分別指向不一致的兩個字段。
@Mapper
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
@Mapping(target = "myEmail", source = "email")
UserInfoDTO toDTO(UserInfo userInfo);
}生成的實(shí)現(xiàn)類
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-07-19T15:22:09+0800",
comments = "version: 1.5.2.Final, compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)
public class UserInfoConvertImpl implements UserInfoConvert {
@Override
public UserInfoDTO toDTO(UserInfo userInfo) {
if ( userInfo == null ) {
return null;
}
UserInfoDTO userInfoDTO = new UserInfoDTO();
// 注意這里,已經(jīng)自動轉(zhuǎn)換了
userInfoDTO.setMyEmail( userInfo.getEmail() );
userInfoDTO.setId( userInfo.getId() );
userInfoDTO.setName( userInfo.getName() );
userInfoDTO.setSex( userInfo.getSex() );
return userInfoDTO;
}
}三、避坑指南
1號坑
Error:(20, 5) java: No property named "***" exists in source parameter(s). Type "***" has no properties.
原因: annotationProcessorPaths中缺少lombok插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<!--缺少lombok-->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
解決辦法:annotationProcessorPaths中加上lombok插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
2號坑
Error:(20, 5) java: No property named "***" exists in source parameter(s). Type "***" has no properties.
如果annotationProcessorPaths有l(wèi)ombok和mapstruct-processor,查看lombok是否放在mapstruct-processor后面,切記lombok要放在mapstruct-processor之前。
錯誤方式:
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
</annotationProcessorPaths>
正確方式:
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
到此這篇關(guān)于Java中的MapStruct的使用方法代碼實(shí)例的文章就介紹到這了,更多相關(guān)MapStruct的使用方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中MapStruct的使用詳解
- Java中MapStruct使用方法解析
- Java中的MapStruct知識點(diǎn)總結(jié)
- Java中的MapStruct實(shí)現(xiàn)詳解
- Java中MapStruct入門使用及對比
- Java高效映射工具M(jìn)apStruct的使用示例
- Java中MapStruct映射處理器報錯的問題解決
- Java高性能實(shí)體類轉(zhuǎn)換工具M(jìn)apStruct的使用教程詳解
- SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制
- SpringBoot使用MapStruct生成映射代碼的示例詳解
- MapStruct升級遇到的問題及解決方案
相關(guān)文章
JAVA正則表達(dá)式及字符串的替換與分解相關(guān)知識總結(jié)
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識總結(jié),文章圍繞著JAVA正則表達(dá)式及字符串的替換與分解展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
SpringBoot + SpringSecurity 短信驗(yàn)證碼登錄功能實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot + SpringSecurity 短信驗(yàn)證碼登錄功能實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
SpringMVC實(shí)現(xiàn)controller中獲取session的實(shí)例代碼
本篇文章主要介紹了SpringMVC實(shí)現(xiàn)controller中獲取session的實(shí)例代碼,具有一定的參考價值,有興趣的可以了解一下。2017-02-02
Java?pdf文件書簽承前縮放驗(yàn)證的設(shè)置方法
很多朋友不知道是什么是書簽承前縮放,簡單說就是可以任意改變當(dāng)前pdf文檔縮放比例,點(diǎn)擊書簽后不影響其縮放比率,本文給大家介紹下Java?pdf文件書簽承前縮放驗(yàn)證的設(shè)置方法,感興趣的朋友一起看看吧2022-02-02
K8S環(huán)境下如何驗(yàn)證RocketMQ擴(kuò)縮容
文章主要內(nèi)容驗(yàn)證了K8S環(huán)境下RocketMQ的擴(kuò)縮容特性,包括序號變化、命名規(guī)則以及節(jié)點(diǎn)重建后序號保持不變,StatefulSet確保Pod序號在重建后保持穩(wěn)定,而Deployment創(chuàng)建的Pod名稱是隨機(jī)的2025-01-01
SpringBoot2+Netty+WebSocket(netty實(shí)現(xiàn)websocket支持URL參數(shù))問題記錄
Netty?是一個利用?Java?的高級網(wǎng)絡(luò)的能力,隱藏其背后的復(fù)雜性而提供一個易于使用的?API?的客戶端/服務(wù)器框架,這篇文章主要介紹了SpringBoot2+Netty+WebSocket(netty實(shí)現(xiàn)websocket,支持URL參數(shù)),需要的朋友可以參考下2023-12-12

