Dozer 对象的"搬运工"
前言:项目中,经常会遇到各层对象之间相互进行值传递的过程,如在数据据持久层有一持久类EntityA,在视图层可能会变为ViewA,通常情况下,这两个类的属性 名称 、类型都是一致的,
在两个对象传值的过程中,有几种办法:
1.最基本的set(),get()方法,当对象的属性有很多时,会产生大量的代码
2.apache的common-beanutils.jar 下 BeanUtils().copyProperties(obj1,obj2)
3.dozer
本文主要介绍dozer的用法
1.简介
dozer是一种JavaBean的映射工具,类似于apache的BeanUtils。但是dozer更强大,它可以灵活的处理复杂类型之间的映射。不但可以进行简单的属性映射、复杂的类型映射、
双向映射、递归映射等,并且可以 通过XML配置文件进行灵活的配置。
使用Dozer映射复杂类型:1. 数据类型不一致。 2. 级联映射。 3. 自定义映射。
Dozer其实底层使用了现成的BeanUtil,通过反射来映射,况且Dozer应用了Cache技术,应该比通过BeanUtils映射性能要好点。所以一般的应用应该不存在性能问题。
2.配置
1.添加spring相关jar(如果单独使用可以不需要配置)
2.添加dozer与spring集成jar(如果单独使用dozer,可以不用dozer-spring,以下所有案例都是与将dozer与spring集成使用)
pom依赖:
<dependency> <groupId>net.sf.dozer</groupId> <artifactId>dozer</artifactId> <version>5.5.1</version> </dependency> <dependency> <groupId>net.sf.dozer</groupId> <artifactId>dozer-spring</artifactId> <version>5.5.1</version> </dependency>
spring配置文件:
<!-- 自动扫描的包名 --> <context:annotation-config/> <context:component-scan base-package="dozer.*"/> <bean id="mapper" class="org.dozer.spring.DozerBeanMapperFactoryBean"> <property name="mappingFiles" value="classpath*:/*-mapper.xml"/> //此处的mapper配置文件是用来处理复杂类型的转换使用 </bean>
3.案列
1.基本属性映射:只会映射属性名相同的值,如果属性名不同,则不会处理
只要属性名相同,基本数据类型之间、String与基本数据类型之间都双向转换
如:int a <--> double a; String b <-->float b;
UserEntity:
public class UserEntity { private Long id; private String name; private int age; private String password; private Date date; private String map; ...get() ...set() ...XXX }
UserVo:
public class UserVO { private Long id; private String userName; private double age; private String password; private String createDate; private float map; ...XXX get() ...set() }
测试类:
@Test public void testDozer(){ UserEntity entity=new UserEntity(2L,"admin",13,"admin",new Date(),"23.7"); UserVO userVO=new UserVO(); mapper.map(entity,userVO); System.out.println(userVO); }
结果:
结果对比,如果属性名不一直,则不会处理
2.对于1中出现属性不一致的情况,我们仍然想要进行值传递,该怎么办呢?这时就要用到<property name="mappingFiles" value="classpath*:/*-mapper.xml"/>配置文件
添加user-mapper.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd"> <!--<configuration>--> <!--<date-format>yyyy-MM-dd HH:mm:ss</date-format>--> <!--</configuration>--> <mapping > <class-a>entity.UserEntity</class-a> <class-b>pojo.UserVO</class-b> <field> <a>name</a> <b>userName</b> </field> <field> <a>date</a> <b>createDate</b> </field> </mapping> </mappings>
运行结果:
每个属性的值都已传递过来,但是注意途中红框中的内容,Date 类型 转 String 类型的时候,String createDate的值并不是我们期望的格式,我们期望将其 装换成 "yyyy-MM-dd HH:mm:ss"格式,或者其他自定义的日期格式,那该怎么办呢? 请看下一点
3.对于2中的问题,String to Date 或 Date to String 转换 这里有三种方式可以解决:
①在属性匹配 上修改配置 使用dozermapper中field的date-format属性
<mapping > <class-a>entity.UserEntity</class-a> <class-b>pojo.UserVO</class-b> <field> <a>name</a> <b>userName</b> </field> <field> <a date-format="yyyy-MM-dd HH:mm:ss">date</a> <b>createDate</b> </field> </mapping>
②在类匹配 上修改配置,使用mapping中的date-format属性
<mapping date-format="yyyy-MM-dd HH:mm:ss"> <class-a>entity.UserEntity</class-a> <class-b>pojo.UserVO</class-b> <field> <a>name</a> <b>userName</b> </field> <field> <a>date</a> <b>createDate</b> </field> </mapping>
③在全局属性上 ,修改配置,使用configuration标签下的date-format标签
<?xml version="1.0" encoding="UTF-8"?> <mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd"> <configuration> <date-format>yyyy-MM-dd HH:mm:ss</date-format> </configuration> <mapping> <class-a>entity.UserEntity</class-a> <class-b>pojo.UserVO</class-b> <field> <a>name</a> <b>userName</b> </field> <field> <a>date</a> <b>createDate</b> </field> </mapping> </mappings>
结果:
4.如果在两个对象间传值,不想要对某个属性赋值,可以使用 field-exclude标签
<mapping> <class-a>entity.UserEntity</class-a> <class-b>pojo.UserVO</class-b> <field> <a>name</a> <b>userName</b> </field> <field> <a>date</a> <b>createDate</b> </field> <field-exclude> <a>unpass</a> <b>unpass</b> </field-exclude> </mapping>
5.级联映射 UserEntity中有个Colleage对象,而UserVO中有个属性schoolName指向UserEntity.Colleage.Name
<field> <a>colleage.name</a> <b>schoolName</b> </field>
至此,dozer最基本"搬运"方法已经介绍完毕,后续会继续学习 其他标签的用法 以及 集合类型的属性匹配。