环境:SpringBoot3.2.5
1. 简介
在项目开发中,实体(Entity)到DTO(Data Transfer Object,数据传输对象)的转换是一个常见的需求,特别是在前后端分离或微服务架构中。实体通常代表数据库中的表结构,包含业务数据和状态,而DTO则是一种用于封装和传输数据的轻量级对象,主要用于在不同层或服务之间传递数据。
实体到DTO的转换过程旨在将复杂的实体对象转换为更简洁、更适合传输的DTO对象,从而隐藏业务逻辑细节,提高数据传输效率和安全性。
有效的实体到DTO转换策略能够减少数据传输量,提升系统性能,并增强系统的可维护性和可扩展性。
- Spring BeanUtils
- Apache BeanUtils
- Orika
- Cglib BeanCopier
- ModelMapper
- MapStruct
- Getter/Setter
以上对象的转换,你用过哪几种?
1.1 环境准备
接下来,我们先准备2个类,Entity与DTO类
实体类与DTO类完全一样。
我们下面的测试都会基于下面的数据进行测试:
接下来,我们将详细的介绍每一种转换工具的基本使用及其性能情况。
2. 性能对比
2.1 Spring BeanUtils
该工具类是Spring提供位于spring-beans.jar包中。如下是基本使用:
接下来我们进行10000次的循环测试
输出结果
平均在55ms完成。
注意:首次进行copyProperties时会慢,因为它内部会通过内省获取属性信息然后缓存,之后直接从缓存中获取,后续速度会非常快。
2.2 Apache BeanUtils
我们需要引入以下包
基本使用示例:
与Spring的基本一样。进行10000次的循环测试
输出结果
该BeanUtils内部也是通过内省+Cache的方式进行处理,但是它的效率相比Spring BeanUtils慢了至少1倍。
2.3 Orika
Orika 能够递归地(以及其他功能)将一个对象的数据复制到另一个对象中。在开发多层应用程序时,它非常有用。
引入以下依赖
基本使用示例:
如果需要我们还可以注册类型字段的映射关系,如下:
类之间的字段如何进行映射。
接下来,进行10000次的循环测试
输出结果
目前来看性能相当不错。
2.4 Cglib BeanCopier
因为我当前是基于Spring Boot环境,而该BeanCopier类位于spring-core.jar包中。
基本使用示例:
与上面的BeanUtils差不多一行代码搞定。进行10000次的循环测试
输出结果
性能更高了。
2.5 ModelMapper
该开源组件,在之前的文章中已经介绍过了,我们这里就不在啰嗦了,我们直接进行10000次测试。
输出结果
似乎不是很理想啊。
2.6 MapStruct
MapStruct 是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java Bean 类型之间映射的实现。生成的映射代码使用普通的方法调用,因此速度快、类型安全且易于理解。
MapStruct在编译时生成bean映射,这确保了高性能。它是一个注解处理器,它被插入到 Java 编译器中,既可以在命令行构建(如 Maven、Gradle 等)中使用。
首先,引入依赖。
我们还需要配置编译插件。
基本使用示例:
定义映射接口
使用
上面的插件会根据这里的映射接口Mapper,自动生成接口实现类
图片
而我们不需要直接去使用该实现类,这是由mapstruct来调用。
进行10000的测试。
输出结果
看起来也还是非常优秀的。
2.7 Getter/Setter
此种方式就是我们自己在代码中进行getter/setter操作。所以,这里我们直接进行10000次的测试
输出结果
虽然要写更多的代码了,但是性能确是最高的。
2.8 最后总结
图片
要论工具的强大,MapStruct 和 ModelMapper 无疑是佼佼者,但相对而言,MapStruct 的配置和使用略显复杂,ModelMapper相对简单多了,不需要额外的插件支持。如果你对性能的要求不是极高,选择 MapStruct 依然是一个明智且不错的选择。然而,如果你追求极致的性能优化,那么手动编写 getter/setter 代码可能会是更优的方案。