简介
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实现实体之间的映射转换。下面两个类非常相似,有一个号码属性名不一样及在PeopleDTO中有个User对象,而在People中则是两个字符串属性。
public class PeopleEntity {
private Integer age;
private String name;
private String callNumber;
private String address;
private String emile;
//constructor, getters, setters etc.
}
public class PeopleDTO {
private String phoneNumber;
private String address;
private String emile;
private User user;
//constructor, getters, setters etc.
}
public class User {
private Integer age;
private String name;
//constructor, getters, setters etc.
}
要生成一个PeopleDTO与PeopleEntity对象相互转换的映射器,我们需要定义一个mapper接口。像这两个实体类有些属性不一样时,我们可以通过@Mapping注解来进行转换.
@Mapper
注解标记这个接口作为一个映射接口,并且是编译时MapStruct处理器的入口。@Mapping
解决源对象和目标对象中,属性名字不同的情况。Mappers.getMapper
自动生成的接口的实现可以通过Mapper的class对象获取,从而让客户端可以访问Mapper接口的实现。
@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是以Java编译器插件的形式来处理注解,生成mapper接口的实现。因此在使用之前我们要手工编译或启动程序时IDEA也会帮我们编译了,这里最好还是手动编译。
mvn compile
// 有的IDEA是 mvnw compile
这时你也可以点进看里面代码的实现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的使用
@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]'}