摘要: 在实际项目中,我们经常需要将PO转DTO、DTO转PO等一些实体间的转换。比较出名的有BeanUtil 和ModelMapper等,它们使用简单,但是在稍显复杂的业务场景下力不从心。MapStruct这个插件可以用来处理domin实体类与model类的属性映射,可配置性强。
MapStruct需要醒目构建工具(如Maven)支持,如果项目结构不标准,可能无法生成对应的转换类。这里我使用Maven构建工程。
<properties>
<org.mapstruct.version>1.2.0.CR1org.mapstruct.version>
properties>
MapStruct是一个一直在进步的工具,后面的版本不断改进之前版本的不足,修复之前版本的bug,使用的时候最好最新的稳定版。
<dependencies>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-jdk8artifactId>
<version>${org.mapstruct.version}version>
dependency>
dependencies>
需要引入的依赖包,可以看到使用到了java8,最新版甚至已经支持了java9。当然这不以为着你必须使用java8,java版本高于java6都是可以的。
<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>
Maven插件必不可少,格式也是固定的。
有一个实体类-用户User
public class User {
private int id;
private String name;
private boolean married;
// setters, getters, toString
有一个实体类-雇员Employee,雇员也是用户,只是比用户多一个属性-职位position
public class Employee {
private int id;
private String name;
private String position;
private boolean married;
// setters, getters, toString
}
在具体业务场景下,需要User 对象转换为Employee对象,有时候需要Employee对象转换为User对象。
使用MapStrut的话,需要写一个接口:
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
Employee userToEmployee(User user);
User employeeToUser(Employee employee);
}
首先需要mvn compile
,自动生成转换代码。生成的代码放在target/annotations
下面。大致代码如下:
import com.training.mapstrut.model.Employee;
import com.training.mapstrut.model.User;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2017-08-26T17:08:23+0800",
comments = "version: 1.2.0.CR1, compiler: javac, environment: Java 1.8.0_92 (Oracle Corporation)"
)
public class UserMapperImpl implements UserMapper {
@Override
public Employee userToEmployee(User user) {
if ( user == null ) {
return null;
}
Employee employee = new Employee();
employee.setId( user.getId() );
employee.setName( user.getName() );
employee.setMarried( user.isMarried() );
return employee;
}
@Override
public User employeeToUser(Employee employee) {
if ( employee == null ) {
return null;
}
User user = new User();
user.setId( employee.getId() );
user.setName( employee.getName() );
user.setMarried( employee.isMarried() );
return user;
}
}
简单的写个测试类实验一下。
public class AppTest{
@Test
public void appTest(){
User user = new User();
user.setId(125);
user.setName("Chao");
user.setMarried(false);
Employee e = UserMapper.INSTANCE.userToEmployee(user);
System.out.println(e);
Assert.assertFalse(e.isMarried());
}
}
结果输出:
Employee [id=125, name=Chao, position=null, married=false]
效果不错,需要转换的字段都准确无误,不过有人要吐糟了,这样的用法比BeanUtil 复杂多了,还只是达到相同的效果。这种简单的转化确实不需要MapStruct,它要做的是更为复杂的业务场景。
MapStruct转换不准确。
MapStruct一直在更新,一些特性在旧版本中无法识别,在使用的时候最要使用比较新的版本。
Eclipse Marketplace
中下载安装,有时候还需要指定下面的配置在pom.xml
的properties中,以启用Annotation Processing jdt_apt
Nothing to compile - all classes are up to date
,你可以试一下在Golds中填写clean install compile
。ClassNotFoundException: Cannot find implementation for com...*Mapper
mapstruct-processor-*.jar
(大概在计算机的目录.m2\repository\org\mapstruct\mapstruct-processor
) – > OK