pom 配置:
| 1 | <properties> | 
关于lombok和mapstruct的版本兼容问题,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外编译的lombok mapstruct的插件不要忘了。否则会出现下面的错误:No property named “aaa” exists in source parameter(s). Did you mean “null”?
这种异常就是lombok编译异常导致缺少get setter方法造成的。还有就是缺少构造函数也会抛异常。
| 1 | 
 | 
实体类是开发过程少不了的,就算是用工具生成肯定也是要有的,需要手写的部分就是这个Mapper的接口,编译完成后会自动生成相应的实现类
然后就可以直接用mapper进行实体的转换了
| 1 | public class Test { | 
mapper可以进行字段映射,改变字段类型,指定格式化的方式,包括一些日期的默认处理。
可以手动指定格式化的方法:
| 1 | 
 | 
上面只是最简单的实体映射处理,下面介绍一些高级用法
List 转换
属性映射基于上面的mapping配置
| 1 | 
 | 
多对象转换到一个对象
| 1 | 
 | 
默认值
| 1 | 
 | 
转换基类
准备工作
使用常见的 User 类以及对应 UserDto 对象来演示。
| 1 | 
 | 
注意观察这两个类的区别。
因为项目中的对象转换操作基本都一样,因此抽取除了一个转换基类,不同对象如果只是简单转换可以直接继承该基类,而无需覆写基类任何方法,即只需要一个空类即可。
如果子类覆写了基类的方法,则基类上的 @Mapping 会失效。
| 1 | 
 | 
实现 User 与 UserVo 对象的转换器
| 1 | import org.mapstruct.Mapper; | 
这里使用的是 Spring 的方式,@Mapper 注解的 componentModel 属性值为 spring,不过应该大多数都用的此模式进行开发。
@Mapping用于配置对象的映射关系,示例中 User 对象性别属性名为 sex,而UserVo对象性别属性名为gender,因此需要配置 target 与 source 属性。
password 字段不应该返回到前台,可以采取两种方式不进行转换,第一种就是在vo对象中不出现password字段,第二种就是在@Mapping中设置该字段 ignore = true。
MapStruct 提供了时间格式化的属性 dataFormat,支持Date、LocalDate、LocalDateTime等时间类型与String的转换。
示例中birthday 属性为 LocalDate 类型,可以无需指定dataFormat自动完成转换,而LocalDateTime类型默认使用的是ISO格式时间,在国内往往不符合需求,因此需要手动指定一下 dataFormat。
自定义属性类型转换方法
一般常用的类型字段转换 MapStruct都能完成,但是有一些是自定义的对象类型,MapStruct就不能进行字段转换,这就需要编写对应的类型转换方法,这里使用的是JDK8,支持接口中的默认方法,可以直接在转换器中添加自定义类型转换方法。
示例中User对象的config属性是一个JSON字符串,UserVo对象中是List类型的,这需要实现JSON字符串与对象的互转。
| 1 | default List<UserConfig> strConfigToListUserConfig(String config) { | 
如果是 JDK8以下的,不支持默认方法,可以另外定义一个 转换器,然后再当前转换器的 @Mapper 中通过 uses = XXX.class 进行引用。
定义好方法之后,MapStruct当匹配到合适类型的字段时,会调用自定义的转换方法进行转换。
单元测试
| 1 | 4j | 
常见问题
当两个对象属性不一致时,比如User对象中某个字段不存在与UserVo当中时,在编译时会有警告提示,可以在@Mapping中配置 ignore = true,当字段较多时,可以直接在@Mapper中设置unmappedTargetPolicy属性或者unmappedSourcePolicy属性为 ReportingPolicy.IGNORE即可。
如果项目中也同时使用到了 Lombok,一定要注意 Lombok的版本要等于或者高于1.18.10,否则会有编译不通过的情况发生。
