bean对象之间的相互映射的工具有不少,比如常见的BeanUtils,dozer,这都基本都是基于反射实现的,但是MapStruct则不同,下面我们就来看看MapStruct的使用方法吧!
MapStruct类似lombok,在编译期生成基于转换规则的 Impl 文件,运行时直接调用 Impl 文件中的函数。所以它的速度是比其他基于反射实现的工具速度要快!!!
代码
1 pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.8</org.projectlombok.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2 实体
@Data
public class Source {
private String name;
private String alias;
private Car car;
@Data
public static class Car {
private String color;
}
}
@Data
public class Target {
private String name;
private String anotherName;
private Car car;
@Data
public static class Car {
private String color;
}
}
3 转换
@Mapper
public interface SourceConvert {
// field不一致的,可以使用@Mapping来指定映射关系
@Mapping(source = "alias", target = "anotherName")
Target sourceToTarget(Source source);
}
4 使用
public class SourceConvertTest {
SourceConvert sourceConvert = null;
@Before
public void init() {
sourceConvert = Mappers.getMapper(SourceConvert.class);
}
@Test
public void sourceToTarget() {
Source source = new Source();
source.setName("jack");
source.setAlias("mini");
Source.Car car = new Source.Car();
car.setColor("black");
source.setCar(car);
Target target = sourceConvert.sourceToTarget(source);
// Target(name=jack, anotherName=mini, car=Target.Car(color=black))
System.out.println(target);
}
}
到这转换已经结束。因为MapStruct是在编译期生成基于转换规则 Impl 文件,所以我们是可以看到编译后生成的SourceConvertImpl的,如下:
public class SourceConvertImpl implements SourceConvert {
public SourceConvertImpl() {
}
public Target sourceToTarget(Source source) {
if (source == null) {
return null;
} else {
Target target = new Target();
target.setAnotherName(source.getAlias());
target.setName(source.getName());
target.setCar(this.carToCar(source.getCar()));
return target;
}
}
protected Car carToCar(cn.justme.common.Source.Car car) {
if (car == null) {
return null;
} else {
Car car1 = new Car();
car1.setColor(car.getColor());
return car1;
}
}
}
所以我们可以很清楚的看到内部转换的逻辑,当转换出现问题时,MapStruct比一些其他工具类更易debug,定位问题。更多功能可以参考官方文档。
5 优势
总结几点优势:
- 速度快
- 类型安全
- 定位问题更方便
- Event handling (
@BeforeMapping, @AfterMapping
)
参考: