MapStruct实体映射转换
1.MapStruct简介
MapStruct是一个代码生成器,它基于约定优于配置的方法,极大地简化了Java bean类型之间映射的实现。生成的映射代码使用简单的方法调用,快速、类型安全且易于理解。应用程序通常需要在不同的对象模型(例如实体和dto、vo)之间进行映射。编写这样的映射代码是一项繁琐且容易出错的任务。MapStruct是通过尽可能地自动化来简化这项工作。与其他映射框架相比,MapStruct在编译时使用原生代码处理,这确保了使用的高性能,同时支持复杂场景使用。出问题时可以快速的错误检查。
2.转换常用方案
fastjson
这种方案因为通过生成中间json格式字符串,然后再转化成目标对象,性能非常差,同时因为中间会生成json格式字符串,如果转化过多,
gc会非常频繁,同时针对复杂场景支持能力不足。
BeanUtil类
只能适合bean数量较少、内容不多、转换不频繁的场景。
apache.BeanUtils
用到反射的原因,同时本身设计问题,性能较差。
spring.BeanUtils(本人经常使用该工具)
spring的BeanUtils做了很多优化,整体性能提升不少,不过还是使用反射实现比不上原生代码处理,其次针对复杂场景支持能力不足。
beanCopier
BeanCopier copier = BeanCopier.create(DO.class, DTO.class, false);
copier.copy(do, dto, null);
整体性能接近原生代码处理,比BeanUtils要好很多,尤其在数据量很大时,但是针对复杂场景支持能力不足。
3.MapStruct依赖
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.0.Final</version>
</dependency>
4.MapStruct使用
创建接口添加@Mapper()注解
@Mapper(componentModel = "spring",
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TestTransfer {
Test add(Test.Add add);
Test update(Test.Update update,@MappingTarget Test test);
@Mapping(target = "titles",source = "title")
@Mapping(target = "contexts",source = "context")
Test.TestVo vo(Test test);
@Mappings({
@Mapping(target = "title",source = "name"),
@Mapping(target = "context",source = "text")
})
Test query(Test.Query query);
}
调用
private final TestTransfer testTransfer;
Test.Add add=Test.Add.builder().title("测试MapStruct").context("测试内容").status("启动").onLine("在线")
.build();
Test test = testTransfer.add(add);
//System.out.println(JSONObject.toJSONString(test));
Test update = testTransfer.update(Test.Update.builder().title("修改测试").build(),test);
// System.out.println(JSONObject.toJSONString(update));
Test.TestVo testVo = testTransfer.vo(test);
// System.out.println(JSONObject.toJSONString(testVo));
Test query = testTransfer.query(Test.Query.builder().name("aaaa").text("测试").build());
//System.out.println(JSONObject.toJSONString(query));
@org.mapstruct.Mapper注解相关属性
componentModel 属性
指定自动生成的接口实现类的组件类型。这个属性支持四个值:
default: 这是默认的情况,mapstruct不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象。
cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject
spring: 生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired方式进行注入
jsr330: 生成的实现类上会添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。
collectionMappingStrategy属性
设置集合的映射策略 属性支持四个值:
ACCESSOR_ONLY 先getList在addAll
SETTER_PREFERRED 先清除目标集合clear(),再addAll(list)。
ADDER_PREFERRED 使用addList方法。
TARGET_IMMUTABLE 使用setList方法
unmappedTargetPolicy 属性
在未使用Mappin填充映射方法的target的属性的情况下默认报告策略
IGNORE 将被忽略
WARN 构建时引起警告
ERROR 映射代码生成失败
@MappingTarget 注解
需要更新的实体