MapStruct用于生成安全的Bean的映射类。
MapStruct采用注解的方式,使用它我们所需要做的就是定一个映射的接口,该接口中声明任何需要的映射方法。在代码的编译期间,由MapStruct生成该接口的实现类。值得注意的是,MapStruct在实现接口的时候并没有采用反射的方式,而是采用普通的java方法来实现的。
简单来说,我们在实际的项目中很多书情况下,都会遇到不同模块层之间的数据进行传递的时候,需要涉及到对象的转换:
1、比如在经典三层的项目架构中,dao层的entity需要传递给控制层的vo进行数据的展示,此时就需要将entity对象转换为vo对象,
2、或者在DDD领域架构设计中,repository中的Po对象需要传递给domain中的领域对象时,也需要涉及到Po对象与entity之间的转化。
3、以及其他情况下的数据对象的转化
对于这种不同数据对象之间的转化,下面这两种方式你一定用到过其中的一个或者多个
- 手动new出目标对象然后将需要转化的属性手动set到目标对象的属性中
- 使用工具类,各种Convert工具类。
实际上,MapStruct的方式本质上是第一种,只不过手动set属性的工作不需要我们来做了,我们要做的只是定义号接口,以及需要映射的方法,加好注解,在项目编译的时候,MapStruct来帮我们实现这部分代码。
MapStruct的优点- 与动态映射框架相比,MapStruct使用普通方法的调用来进行映射,而不是通过反射来实现。我们都知道反射器是降低系统的性能的,所以MapStruct的这种速度更快。
- 编译时类型安全,只能映射互相映射的对象和属性
- 编译时错误检查
创建entity与voorg.mapstruct mapstruct 1.3.0.Final org.mapstruct mapstruct-processor 1.3.0.Final
// entity
@Data
public class User {
private String id;
private String name;
private Integer age;
private String phone;
private String password;
}
//vo
@Data
public class UserVo {
private String id;
private String userName;
private Integer age;
private String mobilePhone;
}
编写映射接口Converter
@Mapper(componentModel = "spring")
public interface UserConverter {
// 将entity映射为vo
@Mapping(source = "name",target = "userName")
@Mapping(source = "phone",target = "mobilePhone")
UserVo toVo(User user);
}
注意,@Mapper注解要引入MapStruct包的
@Mapping注解将名称不一样的属性通过source与target设置进行映射
名称一样的属性可以不编写@Mapping注解
发现数据已经正确的映射成了UserVo的格式,对应的属性也映射正确
注意:如果像我一样使用lombok的注解,代替了编写get和set方法的话,需要注意MapStruct与 lombok的版本依赖问题。如果版本不兼容就会出现下面这个问题
No property named “XXX“ exists in source parameter(s). Did you mean “null“?
这是因为在编译的时候,lombok的还没有将对象属性的get和set方法生成,MapStruct就开始实现映射接口了,由于缺少了get和set方法就会出现这个问题。
目前可用的版本为
MapStruct:1.3.0.final 对应lombok:1.18.10
MapStructDemo 代码下载
MapStruct还有很多值得研究的使用技巧,下篇文章见!



