MapStruct基础

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>

2.5 碰到的问题

  1. idea2020.3 mapstruct1.3.1.Final error

    java: Internal error in the mapping processor: java.lang.NullPointerException at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.java:182) at org.mapstruct.ap.internal.processor.DefaultVersionInformation.openManifest(DefaultVersionInformation.java:153) at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getLibraryName(DefaultVersionInformation.java:129) at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getCompiler(DefaultVersionInformation.java:122) at org.mapstruct.ap.internal.processor.DefaultVersionInformation.fromProcessingEnvironment(DefaultVersionInformation.java:95) at org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext.(DefaultModelElementProcessorContext.java:50) at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:218) at
    

    https://github.com/mapstruct/mapstruct/issues/2290

  2. mapstruct, lombok 联合使用, 易冲突
    https://mapstruct.org/faq/#Can-I-use-MapStruct-together-with-Project-Lombok
    https://github.com/mapstruct/mapstruct-examples/blob/master/mapstruct-lombok/pom.xml

3. 参考

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页