MapStruct基礎

靜湖孤子發表於2020-12-03

MapStruct基礎

本文章, 大都來源於官網的簡單翻譯和加工, mapstruct官網/開始Demo

1. 簡介

MapStruct是一個程式碼生成工具, 主要為了簡化DTO/DO/VO之間, 瑣碎的轉換程式碼.

類似於Lombok, 他也是採用JSR-269, 註解處理器(annotation processor)技術.

在Java原始碼編譯期間, 自動生成, 相關的Getter, Setter, Constuctor, DTO/DO/VO轉換. 等等 程式碼.

2. 開始Demo

2.1 Car, CarDto

public class Car {
 
    private String make;
    private int numberOfSeats;
    private CarType type;
 
    //constructor, getters, setters etc.
}
public class CarDto {
    private String make;
    private int seatCount;
    private String type;
 
    //constructor, getters, setters etc.
}

2.2 CarMapper

/**
 * @Mapper標註此介面是一個Bean轉換介面, 編譯期間, 會自動生成Mapper實現類.
 * 
 * @Mapper 的 componentModel 屬性值
 * 1. default: 預設值, 只能通過 "Mappers#getMapper(Class)" 方式獲取Mapper
 * 2. spring: Spring上下文中, 可以通過 "@Autowired" 方式獲取Mapper
 * 其他兩種屬性, cdi, jsr330 沒研究過, 可以參考原始碼註釋.
 *
 */
// @Mapper
@Mapper(componentModel = "spring")
public interface CarMapper {
  	/**
  	* 執行期間, ClassLoader動態獲取Mapper實現類
  	* 並反射呼叫類構造方法, 生成Mapper物件, 便於其他地方使用.
  	*/
    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
 		
    /**
    * 定義Bean之間轉換的邏輯. 可以有多個@Mapping
    */
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);
}

2.3 CarMapperTest

@RunWith(SpringRunner.class)
@SpringBootTest
public class CarMapperTest {
    /**
     * 方式二: 用spring的方式獲取Mapper
     * 
     * Spring上下文中, 推薦此方式.
     * 另, 生成的Mapper實現, 都是執行緒安全的, 無需擔心多執行緒的情況.
     */
    @Autowired
    private CarMapper carMapper;

    @Test
    public void shouldMapCarToDto() {
        // given
        Car car = new Car( "Morris", 5, Car.CarType.SEDAN );

        // when
        /**
         * 方式一: 用純java的方式獲取Mapper
         */
        // CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
        CarDto carDto = carMapper.carToCarDto( car );

        // then
        Assert.assertNotNull(carDto);
        Assert.assertEquals(carDto.getMake(),"Morris");
        Assert.assertEquals(carDto.getSeatCount() ,5);
        Assert.assertEquals(carDto.getType() ,"SEDAN");

        System.out.println(car);
        System.out.println(carDto);
    }
}

2.4 POM引入mapstruct, mapstruct-processor包

  • org.mapstruct.mapstruct: 包含@Mapper, @Mapping等註解

  • org.mapstruct.mapstruct-processor: 註解處理器, 攔截Java原始碼編譯, 自動生成Mapper實現.

    註解處理器生成的原始碼目錄: target/generated-sources/annotations

  • org.mapstruct.mapstruct-jdk8: 1.2.0.Final版本以後, 已廢棄, 改回用mapstruct包. 可以參考"使用手冊".

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>demo.java.mapstruct</groupId>
    <artifactId>demo-java-mapstruct</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source> <!-- depending on your project -->
                    <target>1.8</target> <!-- depending on your project -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <!-- other annotation processors -->
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3. 參考

相關文章