MapStruct实体间转换

Wu Jun 2019-12-25 15:59:03
Categories: > Tags:

1 简介

MapStruct是一个代码生成器的工具类,简化了不同的Java Bean之间映射的处理,所以映射指的就是从一个实体变化成一个实体。在实际项目中,我们经常会将PO转DTO、DTO转PO等一些实体间的转换。在转换时大部分属性都是相同的,只有少部分的不同,这时我们可以通过mapStruct的一些注解来匹配不同属性,可以让不同实体之间的转换变的简单。

MapStruct官网地址: http://mapstruct.org/

2 配置

Maven配置
    ...
    <properties>
        <org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
    </properties>
    ...
    <dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.6</source> <!-- or higher, depending on your project -->
                    <target>1.6</target> <!-- or higher, depending on your project -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
Gradle配置
    plugins {
        ...
        id 'net.ltgt.apt' version '0.8'
    }
    dependencies {
        ...
        compile 'org.mapstruct:mapstruct:1.3.0.Final'
     
        // OR use this with Java 8 and beyond
        compile 'org.mapstruct:mapstruct-jdk8:1.3.0.Final'
     
        apt 'org.mapstruct:mapstruct-processor:1.3.0.Final'
    }

3 实体

下面我们就来看看如何使用MapStruct实现实体之间的映射转换。下面两个类非常相似,有一个号码属性名不一样及在PeopleDTO中有个User对象,而在People中则是两个字符串属性。

PeopleEntity.java
public class PeopleEntity {
    private Integer age;
    private String name;
    private String callNumber;
    private String address;
    private String emile;
    //constructor, getters, setters etc.
}   
PeopleDTO.java
public class PeopleDTO {
    private String phoneNumber;
    private String address;
    private String emile;
    private User  user;
    //constructor, getters, setters etc.
}
User.java
public class User {
    private Integer age;
    private String name;
    //constructor, getters, setters etc.
}

4 Mapper接口

要生成一个PeopleDTO与PeopleEntity对象相互转换的映射器,我们需要定义一个mapper接口。像这两个实体类有些属性不一样时,我们可以通过@Mapping注解来进行转换.

  1. @Mapper注解标记这个接口作为一个映射接口,并且是编译时MapStruct处理器的入口。
  2. @Mapping解决源对象和目标对象中,属性名字不同的情况。
  3. Mappers.getMapper自动生成的接口的实现可以通过Mapper的class对象获取,从而让客户端可以访问Mapper接口的实现。
PeopleMapper.java
@Mapper
public interface PeopleMapper {
    PeopleMapper INSTANCE = Mappers.getMapper(PeopleMapper.class);

    /**
     * PO转DTO
     *
     * @param entity PO
     * @return DTO
     */
    @Mapping(target = "phoneNumber", source = "callNumber")
    @Mapping(target = "user.name", source = "name")
    @Mapping(target = "user.age", source = "age")
    PeopleDTO entityToDTO(PeopleEntity entity);

    /**
     * DTO转PO
     *
     * @param peopleDTO DTO
     * @param entity    PO
     */
    @Mapping(target = "callNumber", source = "phoneNumber")
    @Mapping(target = "name", source = "user.name")
    @Mapping(target = "age", source = "user.age")
    void updateEntityFromDto(PeopleDTO peopleDTO, @MappingTarget PeopleEntity entity);

}

5 Mapper使用

默认配置

默认配置,我们不需要做过多的配置内容,获取Mapper的方式就是采用Mappers通过动态工厂内部反射机制完成Mapper实现类的获取。

//Mapper接口内部定义
public static GoodInfoMapper MAPPER = Mappers.getMapper(GoodInfoMapper.class);

//外部调用
GoodInfoMapper.MAPPER.from(goodBean,goodTypeBean);
Spring方式配置

Spring方式我们需要在@Mapper注解内添加componentModel属性值,配置后在外部可以采用@Autowired方式注入Mapper实现类完成映射方法调用。

//注解配置
@Mapper(componentModel = "spring")

//注入Mapper实现类
@Autowired
private GoodInfoMapper goodInfoMapper;

//调用
goodInfoMapper.from(goodBean,goodTypeBean);