由于最近公司订单系统数据库重构,上游的交易系统也要重构,所以有大量的异构对象转换工作,所以要求做一个通用的基于配置的复杂对象转换。 主要需求为:假设有A、B两个对象,需要实现 A的属性名和B的属性名不一致, A的子对象和B的子对象不一致, A的子对象是一个LIST和B的子对象LIST不一致, A的某个属性转换为B的属性需要简单的计算, 无限递归,也就是A和B所具有的的子对象层数不确定。 经过研究,发现了一个非常好使的转换工具,DOZER。


需要依赖的JAR包

<dependency>
<groupId>dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency><dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>

核心配置文件

dept:
<?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>
<stop-on-errors>true</stop-on-errors>
<date-format>yyyy-MM-dd hh:mm:ss</date-format>
<wildcard>true</wildcard>
<custom-converters>
<converter type="com.dbtest.common.MyCustomConverter">
<class-a>java.lang.Enum</class-a>
<class-b>java.lang.Integer</class-b>
</converter>
</custom-converters>
</configuration>
<mapping>
<class-a>com.dbtest.entity.SourceDept</class-a>
<class-b>com.dbtest.entity.TargetDept</class-b>
<field>
<a>deptName</a>
<b>name</b>
</field>
<field>
<a>deptId</a>
<b>newId</b>
</field>
<field map-id="User">
<a>sourceUserList</a>
<b>targetUserList</b>
<a-hint>com.dbtest.entity.SourceUser</a-hint>
<b-hint>com.dbtest.entity.TargetUser</b-hint>
</field>
</mapping>
</mappings>
USER:
<?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">
<mapping map-id="User">
<class-a>com.dbtest.entity.SourceUser</class-a>
<class-b>com.dbtest.entity.TargetUser</class-b>
<field>
<a>name</a>
<b>userName</b>
</field>
<field map-id="Info">
<a>sourceInfoList</a>
<b>targetInfoList</b>
<a-hint>com.dbtest.entity.SourceInfo</a-hint>
<b-hint>com.dbtest.entity.TargetInfo</b-hint>
</field>
</mapping>
</mappings>
INFO:
<?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">
<mapping map-id="Info">
<class-a>com.dbtest.entity.SourceInfo</class-a>
<class-b>com.dbtest.entity.TargetInfo</class-b>
<field>
<a>createDate</a>
<b>date</b>
</field>
<field>
<a>gender</a>
<b>gender</b>
</field>
<field>
<a>id</a>
<b>id</b>
</field>
</mapping>
</mappings>

集成SPRING

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"
default-autowire="byName" default-lazy-init="false">

<bean id="beanMapper" class="org.dozer.spring.DozerBeanMapperFactoryBean">
<property name="mappingFiles">
<list>
<value>conf/mapper/*.xml</value>
</list>
</property>
</bean>
</beans>

计算实现

    <field custom-converter="com.dbtest.common.MyCustomConverter">
<a>gender</a>
<b>gender</b>
</field>
转换类:
/**
* 自定义转换类
*
* @author spd
* @create 2013-3-28 下午2:49:39
*/
public class MyCustomConverter implements CustomConverter {

@Override
public Object convert(Object existingDestinationFieldValue,
Object sourceFieldValue, Class<?> destinationClass,
Class<?> sourceClass) {
Object obj = null;
if (null != sourceFieldValue) {
if (sourceFieldValue.equals(GenderType.male))
obj = 1;
else
obj = 2;

}
return obj;
}
}