一、在实际的开发过程中,各个层对象之间的转换是尤为常见的,一个好的转换工具在开发过程中不仅更为方便,而且对性能也是有影响的,如图,在开发过程中常用的一些转换方式。
1、get\set
这种方式也是日常使用的最多的,性能也是最高的。但是一旦对象的属性较多时,操作起来有点麻烦,因此在实际的开发中比较麻烦。
2、json2Json
把对象转JSON串,再把JSON转另外一个对象。
3、Apache copyProperties
Introspector机制获取到类的属性来进行赋值操作。
4、Spring copyProperties
反射的属性拷贝。
5、Bean Mapping
基于属性拷贝
6、Bean Mapping ASM
基于ASM字节码框架实现
7、BeanCopier
基于CGlib字节码操作生成get、set方法。
8、Orika
基于字节码生成映射对象
9、Dozer
属性映射框架,递归的方式复制对象。
10、ModelMapper
基于ASM字节码实现。
11、JMapper
基于映射,速度还可以,但操作起来比较麻烦
12、MapStruct
对象属性转换的操作无非是基于反射、AOP、CGlib、ASM、Javassist 在编译时和运行期进行处理,再有好的思路就是在编译前生成出对应的get、set,就像手写出来的一样。通过以上对接发现MapStruct用起来方便而且性能也是不错的。
二、在实际的开发中VO、DTO、DO、BO之间的转换也是常见的,对于这种这样的转换该怎样正确的使用呢,下面进行说明。
1.VO (View Object),表示一个与前端进行交互的视图对象,即用于某个接口返回前端页面的视图对象。
(1)前到后: 用户发出请求,传递给后台controller接受的对象;
(2)后到前:后端返回个前端的对象,可以 XXVO。
2.DTO(Data Transfer Object),用于表示一个数据传输对象,DTO 通常用于展示层(Controller)和服务层(Service)之间的数据传输对象。
(XXController)把VO转换为服务层(XXServiceImpl)对应方法参数所要求的DTO,传送给服务层(XXServiceImpl)。
3.DO(Data Object) ,持久化对象,它跟持久层(Dao)的数据结构形成一一对应的映射关系。如果持久层是关系型数据库,那么数据库表中的每个字段就对应PO的一个属性,常是entity实体类。
服务层(XXServiceImpl)根据方法参数DTO的数据构造(或重建)出一个DO;然后,调用DO的业务方法完成具体业务。
4.BO(Business Object):业务对象,就是从现实世界中抽象出来的有形或无形的业务实体。
把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。
在开发过程中,有时为了偷懒或者方便,直接将DTO对象返回给前端,这样显得接口输出数据多余,和不安全性,dto作为数据传输对象一般是公用的,VO才是个性化,一旦前端说要说要增加或删字段返回给前端的dto对象 ,就会影响其他业务。因此,总整体性结构而言:vo是必须存在的,不能把dto直接返回给前端。高内聚,低耦合。
VO作为个性化视图对象,一般不建议复用。一般的数据传递是,前端传递VO给接口(Controller),接口将VO转为DTO传递给service,service将DTO分解为DO,调用领域服务进行调度,然后逆向转为VO或者其他的返回结果,传递给前台。