mapstruct中的@Mapper注解詳解

在MapStruct中,@Mapper注解是核心注解之一,用于標記一個接口或抽象類為MapStruct的映射器(Mapper)。MapStruct會在編譯時自動生成該接口的實現類,完成對象之間的屬性映射。以下是對@Mapper注解的詳細解析:


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:標記接口為MapStruct的映射器。
  • Mappers.getMapper(UserMapper.class):獲取MapStruct自動生成的映射器實例。
  • @Mapping:指定屬性映射規則(例如將Userusername屬性映射到UserDTOname屬性)。

2. 常用屬性

@Mapper注解支持多種屬性,用于配置映射器的行為:

(1) componentModel

指定生成的映射器實現類的組件模型,便于與其他框架(如Spring、CDI)集成。

  • 可選值
    • default:默認模型,不依賴任何框架。
    • spring:生成的映射器實現類會帶有@Component注解,便于Spring管理。
    • cdi:生成的映射器實現類會帶有@ApplicationScoped注解,便于CDI管理。
    • jsr330:生成的映射器實現類會帶有@javax.inject.Named@javax.inject.Singleton注解。

示例

@Mapper(componentModel = "spring")
public interface UserMapper {UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);// ...
}
(2) uses

指定其他映射器或工具類,用于在映射過程中調用。

示例

@Mapper(uses = {DateMapper.class})
public interface UserMapper {UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);// ...
}
(3) implementationNameimplementationPackage
  • implementationName:指定生成的映射器實現類的名稱(默認為接口名+Impl)。
  • implementationPackage:指定生成的映射器實現類的包名(默認為接口所在包)。

示例

@Mapper(implementationName = "CustomUserMapperImpl", implementationPackage = "com.example.mappers")
public interface UserMapper {// ...
}
(4) unmappedTargetPolicy

指定當目標對象有未映射的屬性時的處理策略。

  • 可選值
    • ERROR:拋出異常(默認值)。
    • WARN:生成警告日志。
    • IGNORE:忽略未映射的屬性。

示例

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper {// ...
}
(5) injectionStrategy

指定依賴注入的策略。

  • 可選值
    • FIELD:通過字段注入(默認值)。
    • CONSTRUCTOR:通過構造函數注入。
    • METHOD:通過方法注入。

示例

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface UserMapper {// ...
}

3. 高級用法

(1) 結合@MapperConfig

可以通過@MapperConfig定義全局配置,然后在@Mapper中引用。

示例

@MapperConfig(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CommonMapperConfig {
}@Mapper(config = CommonMapperConfig.class)
public interface UserMapper {// ...
}
(2) 自定義方法

可以在映射器接口中定義自定義方法,MapStruct會調用這些方法完成復雜的映射邏輯。

示例

@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. 注意事項

  1. 依賴配置

    • 確保項目中包含MapStruct的依賴和注解處理器(mapstructmapstruct-processor)。
    • 如果使用Lombok,確保Lombok的版本兼容,并在構建工具(如Maven或Gradle)中正確配置。
  2. 映射規則

    • 如果源對象和目標對象的屬性名相同,MapStruct會自動映射。
    • 如果屬性名不同,需要通過@Mapping注解顯式指定。
  3. 性能

    • MapStruct生成的映射代碼是類型安全的,且在編譯時完成,性能優于運行時反射的映射工具(如Apache Commons BeanUtils)。

5. 總結

@Mapper注解是MapStruct的核心,通過它可以:

  • 定義映射器接口。
  • 配置映射器的行為(如組件模型、未映射屬性的處理策略等)。
  • 結合其他注解(如@Mapping)完成復雜的屬性映射。
  • 與其他框架(如Spring)無縫集成。

通過合理使用@Mapper注解及其屬性,可以大大簡化對象之間的映射邏輯,提高開發效率和代碼質量。

6. 編譯異常處理

針對MapStruct項目編譯異常問題,可從依賴配置、IDE設置、代碼規范及版本兼容性四個維度進行排查和解決,以下是具體分析和建議:

依賴配置問題
  • 現象:缺少必要的注解處理器依賴,如org.mapstruct:mapstruct-processor,導致編譯時無法生成Mapper類。
  • 解決方案
    • Maven項目:在pom.xml中添加MapStruct核心庫和處理器依賴,例如:
<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設置問題
  • 現象:IDE未啟用注解處理器或緩存異常,導致編譯時無法正確處理MapStruct注解。
  • 解決方案
    • IntelliJ IDEA:打開“File”菜單,選擇“Settings”,導航至“Build, Execution, Deployment” -> “Compiler” -> “Annotation Processors”,勾選“Enable annotation processing”選項,并清理IDE緩存后重新構建項目。
代碼規范問題
  • 現象:Mapper接口定義錯誤,如方法簽名不匹配或缺少必要注解,導致編譯失敗。
  • 解決方案
    • 驗證Mapper接口:確保接口符合MapStruct規范,例如:
@Mapper
public interface UserMapper {UserDto userToUserDto(User user);
}
- **檢查屬性映射**:如果源對象和目標對象的屬性名不同,需要通過`@Mapping`注解顯式指定,例如:
@Mapper
public interface UserMapper {@Mapping(source = "username", target = "name")UserDto userToUserDto(User user);
}
版本兼容性問題
  • 現象:MapStruct版本與其他依賴(如Lombok)不兼容,導致編譯異常。
  • 解決方案
    • 升級MapStruct版本:嘗試升級至最新穩定版本,例如:
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.6.0.Final</version>
</dependency>
- **解決Lombok沖突**:如果項目中同時使用Lombok和MapStruct,特別是使用Lombok的`@Builder`注解時,可能導致`@AfterMapping`不生效。對于Lombok版本1.18.16或更高版本,需添加`lombok-mapstruct-binding`依賴:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>0.2.0</version>
</dependency>
其他可能的問題及解決方案
  • 未映射的目標屬性:檢查源對象和目標對象,確保存在對應的屬性,或使用@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注解明確指定集合類型的映射方式。
  • 循環引用問題:使用@Context注解通過傳遞上下文對象來避免無限遞歸。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86785.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86785.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86785.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uniapp+vue2+h5圖片下載保存,微信瀏覽器、非微信瀏覽器

小程序端 onDown() {// 檢查相冊權限uni.authorize({scope: scope.writePhotosAlbum,success: () > {this.downloadImage();},fail: () > {uni.showToast({title: "請授權相冊權限",icon: "none"});}}); }, downloadImage() {common.request(post, …

NumPy 與 OpenCV 版本兼容性深度解析:底層機制與解決方案

在計算機視覺項目中&#xff0c;NumPy 和 OpenCV 的兼容性問題常被低估&#xff0c;實則暗藏復雜的技術陷阱。下面從底層機制深入剖析核心兼容性問題及解決方案&#xff1a; 一、內存布局沖突&#xff1a;數組連續性陷阱 問題本質&#xff1a; OpenCV 的 C 內核要求 連續內存塊…

基于SpringBoot利用死信隊列解決RabbitMQ業務隊列故障重試無效場景問題

基于SpringBoot利用死信隊列解決RabbitMQ業務隊列故障重試無效場景問題 解決方案項目實戰1、生產者服務1.1、RabbitConfig定義相關交換機及死信隊列等配置數據1.2、TestController測試接口Controller 2、消費者服務2.1 BusinessQueueConsumer業務隊列監聽器2.2 DeadLetterConsu…

西安java面試總結1

這是我第二次的面試。其實第一次也算不上面試&#xff0c;去了讓我手寫了幾道題&#xff0c;三道算法題&#xff0c;一道SQL題&#xff0c;兩道邏輯思維題&#xff0c;做完之后也沒看我的解答&#xff0c;隨便看了一眼簡歷&#xff0c;覺得我是大二的&#xff0c;大三還有課&am…

【redis】線程IO模型

Redis線程IO模型 總結&#xff1a;在redis5.0及之前&#xff0c;redis線程io模型是單線程。那么Redis單線程如何處理那么多的并發客戶端連接的&#xff1f;原因兩點&#xff1a;1&#xff09;非阻塞io 2&#xff09;多路復用&#xff08;事件輪詢&#xff09; 以下&#xff0…

進程間通信詳解(三):Linux進程信號深度解析

文章目錄 一、Linux進程信號核心概念1.1 信號本質1.2 關鍵術語1.3 Linux 信號機制的核心流程&#xff1a; 二、信號產生機制全景2.1 通過終端按鍵產生信號2.1.1 基本操作 2.2 調用系統命令向進程發信號2.2.1 kill 命令&#xff1a;向指定進程發送信號2.2.2 killall 命令&#x…

C++ 日志系統實戰第五步:日志器的設計

全是通俗易懂的講解&#xff0c;如果你本節之前的知識都掌握清楚&#xff0c;那就速速來看我的項目筆記吧~ 本文項目代碼編寫收尾&#xff01; 日志器類 (Logger) 設計&#xff08;建造者模式&#xff09; 日志器主要用于和前端交互。當我們需要使用日志系統打印 log 時&…

Spring Boot + MyBatis日志前綴清除方法

在 Spring Boot 結合 MyBatis 的應用中&#xff0c;清空日志前綴&#xff08;如 > 、< 等&#xff09;需要通過 自定義 MyBatis 的日志實現 或 修改日志模板 來實現。以下是兩種常用方法&#xff1a; 方法 1&#xff1a;自定義 MyBatis 日志實現&#xff08;推薦&#xf…

【消息隊列】——如何實現消息保序

目錄 一、哪些場景需要消息保序?二、如何實現消息保序?三、保序消息的常見問題和應對策略3.1、重復消息3.2、節點故障3.3、分區擴容四、小結本文來源:極客時間vip課程筆記 一、哪些場景需要消息保序? 消息保序問題指的是,在通過消息中間件傳遞消息過程中,我們希望消費者收…

Transformer模型詳解

Transformer Transformer真是個細節滿滿的框架呢&#xff0c;大三讀到根本不敢看&#xff0c;考研復試前看了看&#xff0c;以為懂了其實差得還遠&#xff0c;兩個多月前看了&#xff0c;還是一知半解&#xff0c;如今終于經過細細分析&#xff0c;算是知道了Transformer的基本…

火山引擎發布豆包大模型 1.6 與視頻生成模型 Seedance 1.0 pro

6 月 11 日&#xff0c;在火山引擎 FORCE 原動力大會上&#xff0c;字節跳動旗下火山引擎正式發布豆包大模型 1.6、豆包?視頻生成模型 Seedance 1.0 pro、豆包?語音播客模型&#xff0c;豆包?實時語音模型也在火山引擎全量上線&#xff0c;豆包大模型家族已成為擁有全模態、…

PH熱榜 | 2025-06-12

1. Atlas 標語&#xff1a;幾秒鐘內了解定價情況 介紹&#xff1a;獲取即插即用的定價頁面&#xff0c;讓你輕松賺錢&#xff0c;不再辛苦操勞。 產品網站&#xff1a; 立即訪問 Product Hunt&#xff1a; View on Product Hunt 關鍵詞&#xff1a;Atlas, 定價快速, 插件式…

ChatGPT革命升級!o3-pro模型重磅發布:開啟AI推理新紀元

2025年6月10日&#xff0c;OpenAI以一場低調而震撼的發布&#xff0c;正式推出了新一代推理模型o3-pro&#xff0c;這標志著人工智能在復雜問題解決領域的重大突破。作為ChatGPT Pro和Team訂閱用戶的專屬工具&#xff0c;o3-pro不僅重新定義了AI的可靠性標準&#xff0c;更以其…

NVIDIA Isaac GR00T N1.5 適用于 LeRobot SO-101 機械臂

系列文章目錄 目錄 系列文章目錄 前言 一、簡介 二、詳細教程 2.1 數據集準備 2.1.1 創建或下載您的數據集 2.1.2 配置模態文件 2.2 模型微調 2.3 開環評估 2.4 部署 &#x1f389; 快樂編程&#xff01;&#x1f4bb;&#x1f6e0;? 立即開始&#xff01; 前言 一…

【編譯工具】(自動化)自動化測試工具:如何讓我的開發效率提升300%并保證代碼質量?

目錄 引言&#xff1a;自動化測試在現代開發中的關鍵作用 一、自動化測試金字塔&#xff1a;構建高效的測試策略 &#xff08;1&#xff09;測試金字塔模型 &#xff08;2&#xff09;各層級代表工具 二、前端自動化測試實戰&#xff1a;Jest Cypress &#xff08;1&…

R語言緩釋制劑QBD解決方案之一

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》緩釋制劑包衣處方研究的R語言解決方案。 ER聚合物包衣處方優化研究 基于初步風險評估和初始可行性研究&#xff0c;進行帶3個中心點的24-1分式析因DOE。藥物的釋放被識別為CQA。本研究的…

行為模式-命令模式

定義&#xff1a; 命令模式是一個高內聚的模式&#xff0c;其定義為&#xff1a;Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.&#xff08;將一個請求封裝成…

Ubuntu 24.04 上安裝與 Docker 部署 Sentinel

Ubuntu 24.04 上安裝與 Docker 部署 Sentinel 一、Sentinel 簡介 Sentinel 是阿里巴巴開源的分布式系統流量控制組件&#xff0c;提供流量控制、熔斷降級和系統負載保護等功能。它通過可視化控制臺&#xff08;Dashboard&#xff09;實現實時監控和規則管理&#xff0c;是微服…

IP 地址查詢在證券交易中的應用方式

網絡安全保障與IP地址查詢 證券交易平臺存儲著海量投資者的敏感信息以及巨額資金的交易數據&#xff0c;是網絡攻擊的重點目標。IP 地址查詢在檢測異常登錄行為方面至關重要。例如&#xff0c;當一個賬戶短時間內先在國內某城市登錄&#xff0c;隨后又在境外 IP 地址發起交易操…

Flutter 常用組件詳解:Text、Button、Image、ListView 和 GridView

Flutter 作為 Google 推出的跨平臺 UI 框架&#xff0c;憑借其高效的渲染性能和豐富的組件庫&#xff0c;已經成為移動應用開發的熱門選擇。本文將深入探討 Flutter 中最常用的五個基礎組件&#xff1a;Text、Button、Image、ListView 和 GridView&#xff0c;幫助開發者快速掌…