mapstruct中的@Mapper注解的基本用法
在MapStruct中,@Mapper注解是核心注解之一,用于標(biāo)記一個接口或抽象類為MapStruct的映射器(Mapper)。MapStruct會在編譯時自動生成該接口的實現(xiàn)類,完成對象之間的屬性映射。以下是對@Mapper注解的詳細(xì)解析:
1. 基本用法
@Mapper注解可以單獨使用,也可以配合其他屬性進行配置。以下是一個簡單的示例:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
@Mapping(source = "username", target = "name")
UserDTO toUserDTO(User user);
}@Mapper:標(biāo)記接口為MapStruct的映射器。Mappers.getMapper(UserMapper.class):獲取MapStruct自動生成的映射器實例。@Mapping:指定屬性映射規(guī)則(例如將User的username屬性映射到UserDTO的name屬性)。
2. 常用屬性
@Mapper注解支持多種屬性,用于配置映射器的行為:
(1) componentModel
指定生成的映射器實現(xiàn)類的組件模型,便于與其他框架(如Spring、CDI)集成。
可選值: default:默認(rèn)模型,不依賴任何框架。
spring:生成的映射器實現(xiàn)類會帶有@Component注解,便于Spring管理。cdi:生成的映射器實現(xiàn)類會帶有@ApplicationScoped注解,便于CDI管理。jsr330:生成的映射器實現(xiàn)類會帶有@javax.inject.Named和@javax.inject.Singleton注解。
示例:
@Mapper(componentModel = "spring")
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// ...
}(2) uses
指定其他映射器或工具類,用于在映射過程中調(diào)用。
示例:
@Mapper(uses = {DateMapper.class})
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// ...
}(3) implementationName 和 implementationPackage
implementationName:指定生成的映射器實現(xiàn)類的名稱(默認(rèn)為接口名+Impl)。implementationPackage:指定生成的映射器實現(xiàn)類的包名(默認(rèn)為接口所在包)。
示例:
@Mapper(implementationName = "CustomUserMapperImpl", implementationPackage = "com.example.mappers")
public interface UserMapper {
// ...
}(4) unmappedTargetPolicy
指定當(dāng)目標(biāo)對象有未映射的屬性時的處理策略。
可選值:
ERROR:拋出異常(默認(rèn)值)。WARN:生成警告日志。IGNORE:忽略未映射的屬性。
示例:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper {
// ...
}(5) injectionStrategy
指定依賴注入的策略。
可選值:
FIELD:通過字段注入(默認(rèn)值)。CONSTRUCTOR:通過構(gòu)造函數(shù)注入。METHOD:通過方法注入。
示例:
@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface UserMapper {
// ...
}3. 高級用法
(1) 結(jié)合@MapperConfig
可以通過@MapperConfig定義全局配置,然后在@Mapper中引用。
示例:
@MapperConfig(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CommonMapperConfig {
}
@Mapper(config = CommonMapperConfig.class)
public interface UserMapper {
// ...
}(2) 自定義方法
可以在映射器接口中定義自定義方法,MapStruct會調(diào)用這些方法完成復(fù)雜的映射邏輯。
示例:
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
@Mapping(target = "fullName", expression = "java(user.getFirstName() + \" \" + user.getLastName())")
UserDTO toUserDTO(User user);
default String formatDate(Date date) {
// 自定義日期格式化邏輯
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
}4. 注意事項
依賴配置:
- 確保項目中包含MapStruct的依賴和注解處理器(
mapstruct和mapstruct-processor)。 - 如果使用Lombok,確保Lombok的版本兼容,并在構(gòu)建工具(如Maven或Gradle)中正確配置。
映射規(guī)則:
- 如果源對象和目標(biāo)對象的屬性名相同,MapStruct會自動映射。
- 如果屬性名不同,需要通過
@Mapping注解顯式指定。
性能:
- MapStruct生成的映射代碼是類型安全的,且在編譯時完成,性能優(yōu)于運行時反射的映射工具(如Apache Commons BeanUtils)。
5. 總結(jié)
@Mapper注解是MapStruct的核心,通過它可以:
- 定義映射器接口。
- 配置映射器的行為(如組件模型、未映射屬性的處理策略等)。
- 結(jié)合其他注解(如
@Mapping)完成復(fù)雜的屬性映射。 - 與其他框架(如Spring)無縫集成。
通過合理使用@Mapper注解及其屬性,可以大大簡化對象之間的映射邏輯,提高開發(fā)效率和代碼質(zhì)量。
6. 編譯異常處理
針對MapStruct項目編譯異常問題,可從依賴配置、IDE設(shè)置、代碼規(guī)范及版本兼容性四個維度進行排查和解決,以下是具體分析和建議:
- 現(xiàn)象:缺少必要的注解處理器依賴,如
org.mapstruct:mapstruct-processor,導(dǎo)致編譯時無法生成Mapper類。 - 解決方案:
- Maven項目:在
pom.xml中添加MapStruct核心庫和處理器依賴,例如:
- Maven項目:在
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
<scope>provided</scope>
</dependency>- **Gradle項目**:在`build.gradle`中添加:
implementation 'org.mapstruct:mapstruct:1.5.3.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
IDE設(shè)置問題
- 現(xiàn)象:IDE未啟用注解處理器或緩存異常,導(dǎo)致編譯時無法正確處理MapStruct注解。
- 解決方案:
- IntelliJ IDEA:打開“File”菜單,選擇“Settings”,導(dǎo)航至“Build, Execution, Deployment” -> “Compiler” -> “Annotation Processors”,勾選“Enable annotation processing”選項,并清理IDE緩存后重新構(gòu)建項目。
代碼規(guī)范問題
- 現(xiàn)象:Mapper接口定義錯誤,如方法簽名不匹配或缺少必要注解,導(dǎo)致編譯失敗。
- 解決方案:
- 驗證Mapper接口:確保接口符合MapStruct規(guī)范,例如:
@Mapper
public interface UserMapper {
UserDto userToUserDto(User user);
}- **檢查屬性映射**:如果源對象和目標(biāo)對象的屬性名不同,需要通過`@Mapping`注解顯式指定,例如:
@Mapper
public interface UserMapper {
@Mapping(source = "username", target = "name")
UserDto userToUserDto(User user);
}版本兼容性問題
- 現(xiàn)象:MapStruct版本與其他依賴(如Lombok)不兼容,導(dǎo)致編譯異常。
- 解決方案:
- 升級MapStruct版本:嘗試升級至最新穩(wěn)定版本,例如:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.0.Final</version>
</dependency>- **解決Lombok沖突**:如果項目中同時使用Lombok和MapStruct,特別是使用Lombok的`@Builder`注解時,可能導(dǎo)致`@AfterMapping`不生效。對于Lombok版本1.18.16或更高版本,需添加`lombok-mapstruct-binding`依賴:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>其他可能的問題及解決方案
- 未映射的目標(biāo)屬性:檢查源對象和目標(biāo)對象,確保存在對應(yīng)的屬性,或使用
@Mapping(target = "property", ignore = true)忽略不需要映射的屬性。 - 枚舉類型映射:自定義映射方法,例如:
@Mapper
public interface EnumConverter {
default TargetEnum toTargetEnum(SourceEnum sourceEnum) {
if (sourceEnum == null) {
return null;
}
switch (sourceEnum) {
case SOURCE_VALUE1:
return TargetEnum.TARGET_VALUE1;
case SOURCE_VALUE2:
return TargetEnum.TARGET_VALUE2;
default:
throw new IllegalArgumentException("Unknown enum type: " + sourceEnum);
}
}
}- 集合類型映射:使用
@IterableMapping注解明確指定集合類型的映射方式。 - 循環(huán)引用問題:使用
@Context注解通過傳遞上下文對象來避免無限遞歸。
到此這篇關(guān)于mapstruct中的@Mapper注解的基本用法的文章就介紹到這了,更多相關(guān)mapstruct @Mapper注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java布爾值Boolean和boolean之間轉(zhuǎn)換實例用法
在本篇文章里小編給大家整理的是一篇關(guān)于Java布爾值Boolean和boolean之間轉(zhuǎn)換實例用法內(nèi)容,有需要的朋友們跟著學(xué)習(xí)參考下。2021-06-06
springboot整合swagger3報Unable to infer base&nbs
這篇文章主要介紹了springboot整合swagger3報Unable to infer base url錯誤問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例
這篇文章主要介紹了Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例,包括將Ext JS中的JSON數(shù)據(jù)解析為列表的方法,需要的朋友可以參考下2016-03-03
加快springboot項目的服務(wù)啟動時間的操作方法
這篇文章給大家介紹如何加快springboot項目的服務(wù)啟動時間,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2025-05-05

