对象映射你用哪个?
对象映射是在业务开发DTO,VO,PO之间相互转化经常遇到的问题。刚入门的程序员把一个对象映射成其他对象往往会使用手动set,比如下面代码A映射到B,手动set会非常枯燥且麻烦,特别是当属性值非常多的时候。
class A { String f1, Long f2, ..... } class B { String f1, Long f2, ..... } public void mapAtoB(A a, B b) { B.f1 = A.f1; B.f2 = A.f2; ..... }
对象映射的三种方式
最近接手了一个其他组的项目,发现在项目中对象映射上竟然采用了三种不同方法:BeanUtil, Orika和MapStruct。BeanUtil是Spring框架自带的映射工具, Orika和Mapstruct是开源的对象映射的两种方法。下面的代码分别使用不同的方式进行对象映射
//BeanUtil BeanUtils.copyProperties(a, b) //Orika private static final MapperFacade FACADE = new DefaultMapperFactory.Builder().build().getMapperFacade(); b = FACADE.map(a, B.class); //MapStruct public interface Converter { Converter INSTANCE = Mappers.getMapper(Converter.class); B b = convertToEntity(A a);
对比
如果只是对比代码量,BeanUils的方式是最简单的,代码量最少,但是在实际的工作场景中会发现使用BeanUils是最坑的,比如传了Null的对象进去,就会报NPE的错误,需要在映射前进行判空的处理。下面是对三种方式的比较。
BeanUtils
优点
- 易于使用和配置。
- 不需要进行手动配置。
- 支持复制对象的属性。
缺点
- 映射速度较慢,因为它使用反射来获取和设置属性。
- 在处理复杂映射场景时可能会出现问题。
- 不支持自定义转换器和过滤器。
Orika
优点
- 映射速度非常快,因为它使用字节码生成来创建映射器。
- 支持复杂的映射场景,例如嵌套对象和集合映射。
- 可以通过自定义转换器和过滤器来进行高度个性化的映射。
- 易于使用和配置。
缺点
- Orika的字节码生成可能会导致应用程序的启动时间变慢。
- 需要在运行时生成字节码,这可能会影响应用程序的性能。
- 需要对映射器进行手动配置。
MapStruct
优点
- 映射速度非常快,因为它使用编译时生成的代码。
- 支持复杂的映射场景,例如嵌套对象和集合映射。
- 可以通过自定义转换器和过滤器来进行高度个性化的映射。
- 易于使用和配置。
缺点
- MapStruct的编译时代码生成可能会导致编译时间变长。
- 需要对映射器进行手动配置。
当选择这些工具中的一个时,应该考虑应用程序的特定需求。如果应用程序需要高性能和复杂的映射场景,则可以选择Orika或MapStruct。如果应用程序需要简单的属性复制,则可以选择BeanUtils。在Orika和MapStruct之间进行选择时,应该考虑是否更关注应用程序的启动时间还是编译时间。
代码可读性
从代码可读性和重构的角度来看,个人认为MapStruct是最佳选择。
MapStruct的代码生成是在编译时完成的,这意味着它生成的代码可以与手动编写的代码一样清晰和易于理解。此外,MapStruct生成的代码易于重构和维护,因为它们与手动编写的代码没有区别。
相比之下,Orika和BeanUtils生成的代码通常比手写的代码难以阅读和理解,这可能会导致在重构和维护代码时出现问题。Orika的字节码生成也可能会使代码变得更加复杂和难以调试。
因此,从代码可读性和重构的角度来看,MapStruct是最佳选择。它生成的代码清晰易懂,易于维护和重构。