这篇“性能爆棚的实体转换复制工具MapStruct如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“性能爆棚的实体转换复制工具MapStruct如何使用”文章吧。
Java项目中实体转换无处不在,当实体字段较多或者大批量的进行复制时,通过手工setter/getter显得太LOW,同时兼备高性能要求情况下,MapStruct完全完全能够胜任。官方解释,MapStruct是一个代码生成器,它基于约定优于配置的方法,极大地简化了Java bean类型之间映射的实现。生成的映射代码使用普通方法调用,因此快速、类型安全且易于理解。因为MapStruct是在编译期间生成setter/getter方法,实际运行时就是直接调用setter/getter,效率会非常高。
MapStruct编译期生成映射代码,所以可以在编译时暴露映射错误的代码,让错误提前暴露;
因为使用setter/getter方式,而非反射方式,所以可以更快的执行效率;
可以实现深拷贝,自动类型转换,如枚举转换;
进行自定义的映射,多种映射方式,下边具体说明;
对比对象 | 10个对象复制1次 | 1万个对象复制1次 | 100万个对象复制1次 | 100万个对象复制5次 |
---|---|---|---|---|
MapStruct | 0ms | 3ms | 96ms | 281ms |
Hutools的BeanUtil | 23ms | 102ms | 1734ms | 8316ms |
Spring的BeanUtils | 2ms | 47ms | 726ms | 3676ms |
Apache的BeanUtils | 20ms | 156ms | 10658ms | 52355ms |
Apache的PropertyUtils | 5ms | 68ms | 6767ms | 30694ms |
<!-- MapStruct核心,包含了一些必要的注解--> <dependencies> <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.1</version> <configuration> <source>1.8</source> <target>1.8</target> <annotationProcessorPaths> <!-- MapStruct编译,注解处理器,根据注解自动生成Mapper的实现 --> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
/** * 测试接口 * * @author reboot */ @Mapper public interface OrderConvertor { /** * 实例 */ OrderConvertor INSTANCE = Mappers.getMapper(OrderConvertor.class); /** * OrderDo -> OrderModel * * @param orderDo 订单实体 * @return {@link OrderModel} */ OrderModel toModel(OrderDo orderDo); /** * OrderDo -> OrderModel * * @param orderDos 订单实体 * @return {@link OrderModel} */ List<OrderModel> toModel(List<OrderDo> orderDos); /** * OrderModel -> OrderDo * * @param orderModel 订单模型 * @return {@link OrderDo} */ OrderDo toDo(OrderModel orderModel); /** * OrderModel -> OrderDo * * @param orderModels 订单模型 * @return {@link OrderDo} */ List<OrderDo> toDo(List<OrderModel> orderModels); }
MapStruct会自动生成对应接口的实现,并自动完成属性映射关系,List会自动进行批量处理。
/** * 订单服务 * * @author reboot */ @Service public class OrderService { /** * 获取订单列表 * * @return {@link List}<{@link OrderModel}> */ public List<OrderModel> getOrderList() { // 获取数据库数据DO List<OrderDo> result = selectOrderList(); // 参数转换 return OrderConvertor.INSTANCE.toModel(result); } }
上边的使用方式虽然能够正常使用,但是在一些属性配置映射上和提示上,如果使用插件能够提升使用体验,IDEA中可以直接安装Mapstruct Support插件,当然Eclipse也有对应的插件。
突出显示目标属性和源属性。将目标属性和源属性转到声明的setter / getter中;
错误和快速修复:
缺少@Mapper或@MapperConfig注解检查;
快速修复未映射的目标属性,添加未映射目标属性和忽略未映射目标属性;
更加详细的内容可以查看官方文档,发布文章时最新版本是 MapStruct 1.5.3.Final.html。
@Mapper public interface CarMapper { @Mapping(target = "manufacturer", source = "make") @Mapping(target = "seatCount", source = "numberOfSeats") CarDto carToCarDto(Car car); @Mapping(target = "fullName", source = "name") PersonDto personToPersonDto(Person person); }
target表示目标属性名,source表示源属性名,一般在目标属性和源属性不同时使用,相同的属性名会自动进行映射。
@Mapper public interface CarMapper { @Mapping(...) ... CarDto carToCarDto(Car car); default PersonDto personToPersonDto(Person person) { //hand-written mapping logic } }
自定义方法personToPersonDto并实现,在生成的实现类中会进行覆盖使用。
@Mapper public interface AddressMapper { @Mapping(target = "description", source = "person.description") @Mapping(target = "houseNumber", source = "address.houseNo") DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address); @Mapping(target = "description", source = "person.description") @Mapping(target = "houseNumber", source = "hn") DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn); }
存在多个源参数,使用参数名.属性名的方式进行表示,也可以直接使用基础类型的属性名称。
@Mapper public interface CustomerMapper { @Mapping( target = "name", source = "record.name" ) @Mapping( target = ".", source = "record" ) @Mapping( target = ".", source = "account" ) Customer customerDtoToCustomer(CustomerDto customerDto); }
当源参数中存在对象属性,可以手动进行映射,或者直接使用"."的方式将对象中的属性全部映射到当前目标对象。
@Mapper public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mapping( target = "timeAndFormat", expression = "java( new org.sample.TimeAndFormat( s.getTime(), s.getFormat() ) )" ) Target sourceToTarget(Source s); }
支持使用java代码块进行转换,一般可以将静态方法处理的字段放到这里。
@Mapper public interface CarMapper { void updateCarFromDto(CarDto carDto, @MappingTarget Car car); }
@MappingTarget源参数,编译时会将carDto参数中的属性映射到car参数中。
@Mapper public interface CustomerMapper { @Mapping(target = "name", source = "customerName") Customer toCustomer(Map<String, String> map); }
直接将map中的key进行映射。
还有更多其他用法,比如:
支持映射定义的public属性;
支持映射参数Builder模式;
使用注入方式引入转换器;
数据类型字段转换,如枚举、日期,支持日期格式化,支持数字类型格式化,具体可以看 Implicit type conversions;
集合类型自动转换;
转换Stream。
以上就是关于“性能爆棚的实体转换复制工具MapStruct如何使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。