package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import javax.annotation.Generated; @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-07-02T23:58:56+0800", comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_371 (Oracle Corporation)" ) public class SubjectCategoryDTOConverterImpl implements SubjectCategoryDTOConverter { @Override public SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO) { if ( subjectCategoryDTO == null ) { return null; } SubjectCategoryBO subjectCategoryBO = new SubjectCategoryBO(); subjectCategoryBO.setId( subjectCategoryDTO.getId() ); subjectCategoryBO.setCategoryName( subjectCategoryDTO.getCategoryName() ); subjectCategoryBO.setCategoryType( subjectCategoryDTO.getCategoryType() ); subjectCategoryBO.setImageUrl( subjectCategoryDTO.getImageUrl() ); subjectCategoryBO.setParentId( subjectCategoryDTO.getParentId() ); subjectCategoryBO.setCount( subjectCategoryDTO.getCount() ); return subjectCategoryBO; } }
MapStruct是一個用於Java的程式碼生成庫,主要用於簡化物件到物件對映的程式碼編寫工作。它的主要目標是減少在物件之間進行屬性複製時所需的手動編碼量,同時保持高效能和型別安全。
MapStruct的工作原理
MapStruct透過註解處理器(Annotation Processor)在編譯時自動生成對映器(Mapper)的實現。(注意報錯後重新整理一下maven,推薦clean,install),否則自動生成類不會更新。當你在介面上應用@Mapper
註解後,MapStruct會自動分析介面中的對映方法,並在編譯期間生成相應的實現類。這些生成的類可以高效地執行物件之間的欄位對映,而無需在執行時進行反射,從而提高了效能。
使用MapStruct的基本步驟
-
定義對映介面: 在一個介面上新增
@Mapper
註解,該介面將包含對映方法的宣告。Java1@Mapper 2public interface MyMapper { 3 // 定義對映方法 4 DestinationClass map(SourceClass source); 5}
-
實現對映方法: MapStruct會自動為介面中的對映方法生成實現。你可以選擇使用預設的欄位對映,也可以透過
@Mapping
註解指定更復雜的對映規則。Java1@Mapper 2public interface MyMapper { 3 @Mapping(source="sourceField", target="destinationField") 4 DestinationClass map(SourceClass source); 5}
-
使用對映器: 在應用程式中,可以透過依賴注入或直接例項化的方式使用對映器。
Java1MyMapper myMapper = ...; // 透過DI框架獲取或直接例項化 2DestinationClass destination = myMapper.map(source);
MapStruct的特點
- 程式碼生成:MapStruct在編譯時生成高效的對映器實現,避免了執行時的開銷。
- 型別安全:由於對映器是在編譯時生成的,因此可以確保型別安全,避免執行時錯誤。
- 靈活性:允許在對映過程中進行條件判斷、資料轉換和業務邏輯處理。
- 可擴充套件性:可以自定義對映器的行為,例如透過自定義註解或實現特定的對映策略。
- 整合性:與Spring和其他依賴注入框架有良好的整合,使得對映器的使用更加方便。
MapStruct的配置和整合
在Maven或Gradle專案中,你需要新增MapStruct的依賴以及相應的編譯外掛或註解處理器。例如,在Maven的pom.xml
中,你可能需要新增以下依賴和外掛:
Xml
1<dependencies>
2 <dependency>
3 <groupId>org.mapstruct</groupId>
4 <artifactId>mapstruct</artifactId>
5 <version>最新版本號</version>
6 </dependency>
7</dependencies>
8
9<build>
10 <plugins>
11 <plugin>
12 <groupId>org.apache.maven.plugins</groupId>
13 <artifactId>maven-compiler-plugin</artifactId>
14 <version>最新版本號</version>
15 <configuration>
16 <source>1.8</source>
17 <target>1.8</target>
18 </configuration>
19 </plugin>
20 <plugin>
21 <groupId>org.mapstruct</groupId>
22 <artifactId>mapstruct-maven-plugin</artifactId>
23 <version>最新版本號</version>
24 <executions>
25 <execution>
26 <goals>
27 <goal>process</goal>
28 </goals>
29 </execution>
30 </executions>
31 </plugin>
32 </plugins>
33</build>
在Gradle的build.gradle
檔案中,配置類似,但使用的是不同的語法。
總之,MapStruct是一個強大的工具,它極大地簡化了Java應用程式中物件對映的任務,同時提供了高度的定製性和效能。
一定要主要mapstruct方法自動生成的內容
轉換語句每次轉換均失敗
SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertBoToCategory(subjectCategoryDTO);
System.out.println("subjectCategoryBO1"+subjectCategoryBO);
System.out.println("subjectCategoryBO1"+subjectCategoryBO);
查詢了確保subjectCategoryBO ,subjectCategoryDTO欄位內容均一致,結果依舊轉換失敗,最後發現初次生成的快取程式碼未更新,導致欄位丟失。
重構maven成功解決。
轉換程式碼如下:
controller層
@PostMapping ("/add") public Result<Boolean> add(@RequestBody SubjectCategoryDTO subjectCategoryDTO) { // 記錄請求資料 log.debug("Received SubjectCategoryDTO: {}", subjectCategoryDTO); System.out.println(subjectCategoryDTO); // 引數校驗 if (subjectCategoryDTO == null || StringUtils.isEmpty(subjectCategoryDTO.getCategoryName())) { return Result.fail(); } try { // 轉換前記錄原始資料 log.debug("Converting SubjectCategoryDTO to SubjectCategoryBO..."); if (subjectCategoryDTO!=null) { // 執行轉換 SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertBoToCategory(subjectCategoryDTO); System.out.println("subjectCategoryBO1"+subjectCategoryBO); // 轉換後檢查 if (subjectCategoryBO == null) { log.error("Conversion from DTO to BO failed."); return Result.fail(); }
converter類
package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import com.jingdianjichi.subject.domain.service.SubjectCategoryDomainService; @Mapper public interface SubjectCategoryDTOConverter { SubjectCategoryDTOConverter INSTANCE = Mappers.getMapper(SubjectCategoryDTOConverter.class); SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO); // List<SubjectCategoryBO> convertBoToCategory(List<SubjectCategory> categoryList); }
最後檢視自動生成的快取是否有問題
package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import javax.annotation.Generated; @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-07-02T23:58:56+0800", comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_371 (Oracle Corporation)" ) public class SubjectCategoryDTOConverterImpl implements SubjectCategoryDTOConverter { @Override public SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO) { if ( subjectCategoryDTO == null ) { return null; } SubjectCategoryBO subjectCategoryBO = new SubjectCategoryBO(); subjectCategoryBO.setId( subjectCategoryDTO.getId() ); subjectCategoryBO.setCategoryName( subjectCategoryDTO.getCategoryName() ); subjectCategoryBO.setCategoryType( subjectCategoryDTO.getCategoryType() ); subjectCategoryBO.setImageUrl( subjectCategoryDTO.getImageUrl() ); subjectCategoryBO.setParentId( subjectCategoryDTO.getParentId() ); subjectCategoryBO.setCount( subjectCategoryDTO.getCount() ); return subjectCategoryBO; } }