MapStruct实体间转换快速入门

  • 简介

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

  • 搭建开发环境 –基于Maven

    这里需要在配置文件pom.xml中进行如下配置:

...
<properties>
    
      <org.mapstruct.version>1.1.0.Finalorg.mapstruct.version>
properties>
...
<dependencies>
    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstruct-jdk8artifactId>
        <version>${org.mapstruct.version}version>
    dependency>
     <dependency>
            <groupId>org.mapstructgroupId>
            <artifactId>mapstruct-processorartifactId>
            <version>${org.mapstruct.version}version>
        dependency>
   
        dependency>
 dependencies>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.pluginsgroupId>
            <artifactId>maven-compiler-pluginartifactId>
            <version>3.5.1version>
            <configuration>
                <source>1.8source>
                <target>1.8target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstructgroupId>
                        <artifactId>mapstruct-processorartifactId>
                        <version>${org.mapstruct.version}version>
                    path>
                annotationProcessorPaths>
            configuration>
        plugin>
    plugins>build>
...


  • MapStruct实体间的转换

下面我们就来看看如何使用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.
}


  • 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);

}


  • 编译MapStruct

MapStruct是以Java编译器插件的形式来处理注解,生成mapper接口的实现。因此在使用之前我们要手工编译或启动程序时IDEA也会帮我们编译了,这里最好还是手动编译。
mvn compile
// 有的IDEA是  mvnw compile

编译完后的实现类可以到target目录看到PeopleMapperImpl.Java,如下图:

MapStruct实体间转换快速入门_第1张图片

这时你也可以点进看里面代码的实现PeopleMapperImpl.Java

public class PeopleMapperImpl implements PeopleMapper {
    public PeopleMapperImpl() {
    }

    public PeopleDTO entityToDTO(PeopleEntity entity) {
        if(entity == null) {
            return null;
        } else {
            PeopleDTO peopleDTO = new PeopleDTO();
            User user = new User();
            peopleDTO.setUser(user);
            user.setAge(entity.getAge());
            user.setName(entity.getName());
            peopleDTO.setPhoneNumber(entity.getCallNumber());
            peopleDTO.setAddress(entity.getAddress());
            peopleDTO.setEmile(entity.getEmile());
            return peopleDTO;
        }
    }

    public void updateEntityFromDto(PeopleDTO peopleDTO, PeopleEntity entity) {
        if(peopleDTO != null) {
            entity.setName(this.peopleDTOUserName(peopleDTO));
            entity.setCallNumber(peopleDTO.getPhoneNumber());
            entity.setAge(this.peopleDTOUserAge(peopleDTO));
            entity.setAddress(peopleDTO.getAddress());
            entity.setEmile(peopleDTO.getEmile());
        }
    }

    private String peopleDTOUserName(PeopleDTO peopleDTO) {
        if(peopleDTO == null) {
            return null;
        } else {
            User user = peopleDTO.getUser();
            if(user == null) {
                return null;
            } else {
                String name = user.getName();
                return name == null?null:name;
            }
        }
    }

    private Integer peopleDTOUserAge(PeopleDTO peopleDTO) {
        if(peopleDTO == null) {
            return null;
        } else {
            User user = peopleDTO.getUser();
            if(user == null) {
                return null;
            } else {
                Integer age = user.getAge();
                return age == null?null:age;
            }
        }
    }
}


  • Mapper使用

最后我们就来看看Mapper的使用
@SpringBootApplication
public class MapperTestApplication {
    private static final Logger LOGGER = LoggerFactory.getLogger(MapperTestApplication.class);

    public static void main(String[] args) {

        //PO转DTO
        PeopleEntity peopleEntity = new PeopleEntity(18, "yoyo", "13215849",
                "shanghai ", "[email protected]");
        PeopleDTO peopleDTO = PeopleMapper.INSTANCE.entityToDTO(peopleEntity);

        //DTO转PO
        User user = new User(21, "jack");
        PeopleDTO newP = new PeopleDTO("000000",
                "changsha ", "[email protected]", user);
        PeopleEntity newEntity = new PeopleEntity();
        PeopleMapper.INSTANCE.updateEntityFromDto(newP, newEntity);


        LOGGER.info("PO转DTO peopleEntity==>" + peopleEntity.toString() + "\n peopleDTO==>" + peopleDTO.toString());
        LOGGER.info("DTO转PO PeopleDTO==>" + newP.toString() + "\n peopleDTO==>" + newEntity.toString());

        SpringApplication.run(MapperTestApplication.class, args);
    }
}

启动之后你可以在后台看到如下的输出

11:12:28.602 [main] INFO com.example.demo.MapperTestApplication - PO转DTO peopleEntity==>PeopleEntity{age=18, name='yoyo', callNumber='13215849', address='shanghai ', emile='[email protected]'}
 peopleDTO==>PeopleDTO{phoneNumber='13215849', address='shanghai ', emile='[email protected]', user=User{age=18, name='yoyo'}}
11:12:28.604 [main] INFO com.example.demo.MapperTestApplication - DTO转PO PeopleDTO==>PeopleDTO{phoneNumber='000000', address='changsha ', emile='[email protected]', user=User{age=21, name='jack'}}
 peopleDTO==>PeopleEntity{age=21, name='jack', callNumber='000000', address='changsha ', emile='[email protected]'}

通过从上面后台输出的数据我们可以看出,对于属性名称不同的情况、以及属性类型不同都自动帮助我们转换了,是不是感觉很神奇,是不是感觉很强大.再也不用自己写大量的代码进行实体间的转换了。

你可能感兴趣的:(java)