准确的说,是因为pojo无法一招走天下或者说内外部隔离的原因,所以有些时候,不得不在两个bean之间做copy或者转换映射。对于直接性的属性拷贝beanutil以及能够满足大部分要求,但是如果遇到字段不一致或者需要二次处理的情况下,就需要进行人工代码处理了。而且这些重复除非通过某种方式管理起来,不然系统中会有大量的复制粘贴。
周六的时候,一个同事说他们那边使用的dozer,还挺好用的,于是看了下官方手册http://dozer.sourceforge.net/dozer-user-guide.pdf,确实比较灵活,有点类似于mybatis之余jdbc原生代码。DEMO示例(实际使用中建议使用spring IOC方式,以及classpath加载,故非以教程式,而是直接可用的代码为例子)如下。
原bean:
package test; public class SourceObject { private String srcName; private int age; private String notMatch; public String getSrcName() { return srcName; } public void setSrcName(String srcName) { this.srcName = srcName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getNotMatch() { return notMatch; } public void setNotMatch(String notMatch) { this.notMatch = notMatch; } }
目标bean:
package test; public class DestinationObject { private String destName; private int age; private String notExist; private String dictName; public String getDestName() { return destName; } public void setDestName(String destName) { this.destName = destName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getNotExist() { return notExist; } public void setNotExist(String notExist) { this.notExist = notExist; } public String getDictName() { return dictName; } public void setDictName(String dictName) { this.dictName = dictName; } public void dictSet(String destName) { this.dictName = "dict " + destName; } }
转换映射文件:
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>truestop-on-errors> <date-format>MM/dd/yyyy HH:mmdate-format> <wildcard>truewildcard> configuration> <mapping> <class-a>test.SourceObjectclass-a> <class-b>test.DestinationObjectclass-b> <field> <a>srcNamea> <b>destNameb> field> <field> <a>srcNamea> <b set-method="dictSet">dictNameb> 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd" default-autowire="byName" default-lazy-init="false"> <bean id="mapper" class="org.dozer.spring.DozerBeanMapperFactoryBean"> <property name="mappingFiles"> <list> <value>classpath*:*DTOMapper.xmlvalue> list> property> bean> beans>
测试类:
package test; import org.dozer.DozerBeanMapper; import org.dozer.Mapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import com.alibaba.fastjson.JSON; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-dozer.xml"}) @TransactionConfiguration(defaultRollback = false) public class DozerBeanMapperTest { @Autowired Mapper mapperNotDefault; @Test public void testDozerBeanMapper(){ SourceObject sourceObject = new SourceObject(); sourceObject.setAge(1); sourceObject.setNotMatch("notmatch"); sourceObject.setSrcName("name1"); DestinationObject destObject; Mapper mapper = new DozerBeanMapper(); destObject = mapper.map(sourceObject, DestinationObject.class); System.out.println(JSON.toJSONString(sourceObject)); System.out.println(JSON.toJSONString(destObject)); destObject = mapperNotDefault.map(sourceObject, DestinationObject.class); System.out.println(JSON.toJSONString(sourceObject)); System.out.println(JSON.toJSONString(destObject)); } }
输出如下:
{"age":1,"notMatch":"notmatch","srcName":"name1"}
{"age":1}
{"age":1,"notMatch":"notmatch","srcName":"name1"}
{"age":1,"destName":"name1","dictName":"dict name1"}