微服務架構MapStruct屬性對映

橘子味芬达水發表於2024-07-03
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的基本步驟

  1. 定義對映介面: 在一個介面上新增@Mapper註解,該介面將包含對映方法的宣告。

    Java
    1@Mapper
    2public interface MyMapper {
    3    // 定義對映方法
    4    DestinationClass map(SourceClass source);
    5}
  2. 實現對映方法: MapStruct會自動為介面中的對映方法生成實現。你可以選擇使用預設的欄位對映,也可以透過@Mapping註解指定更復雜的對映規則。

    Java
    1@Mapper
    2public interface MyMapper {
    3    @Mapping(source="sourceField", target="destinationField")
    4    DestinationClass map(SourceClass source);
    5}
  3. 使用對映器: 在應用程式中,可以透過依賴注入或直接例項化的方式使用對映器。

    Java
    1MyMapper 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);
查詢了確保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;
    }
}

相關文章