一、简介
分析多层架构的JEE系统,经常存在JavaBean直接的拷贝,典型的解决方案就是手动拷贝,弊端很明显,代码中充斥大量Set Get方法,真正的业务没埋藏与值的拷贝之中.另一种方案就是使用BeanUtil,但BeanUtil不够很好的灵活性,又时候还不得不手动拷贝。
Dozer提供了一种非常好的解决方案。
Dozer 是一个对象转换工具。 Dozer可以在JavaBean到JavaBean之间进行递归数据复制,并且这些JavaBean可以是不同的复杂的类型。 所有的mapping,Dozer将会很直接的将名称相同的fields进行复制,如果field名不同,或者有特别的对应要求,则可以在xml中进行定义。 更多详细请参考dozer官网:http://dozer.sourceforge.net/documentation/about.html 。
二、下载
1、http://sourceforge.net/projects/dozer/files/
2、在maven中,pom文中加入:
- <dependency>
- <groupId>net.sf.dozer</groupId>
- <artifactId>dozer</artifactId>
- <version>5.4.0</version>
- </dependency>
三、示例
po Book类
- package dozer;
- import java.util.Date;
- /**
- * @author zhuc
- * @create 2013-3-28 下午1:57:50
- */
- public class Book {
- private Integer id;
- private String name;
- private String author;
- private String capacity;
- private Date birthday;
- private String bookTypeName;
- private Integer source;
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
- /**
- * @return the author
- */
- public String getAuthor() {
- return author;
- }
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
- /**
- * @param author the author to set
- */
- public void setAuthor(String author) {
- this.author = author;
- }
- /**
- * @return the capacity
- */
- public String getCapacity() {
- return capacity;
- }
- /**
- * @param capacity the capacity to set
- */
- public void setCapacity(String capacity) {
- this.capacity = capacity;
- }
- /**
- * @return the id
- */
- public Integer getId() {
- return id;
- }
- /**
- * @param id the id to set
- */
- public void setId(Integer id) {
- this.id = id;
- }
- /**
- * @return the birthday
- */
- public Date getBirthday() {
- return birthday;
- }
- /**
- * @param birthday the birthday to set
- */
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- /**
- * @return the bookTypeName
- */
- public String getBookTypeName() {
- return bookTypeName;
- }
- /**
- * @param bookTypeName the bookTypeName to set
- */
- public void setBookTypeName(String bookTypeName) {
- this.bookTypeName = bookTypeName;
- }
- /**
- * @return the source
- */
- public Integer getSource() {
- return source;
- }
- /**
- * @param source the source to set
- */
- public void setSource(Integer source) {
- this.source = source;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "Book [id=" + id + ", name=" + name + ", author=" + author + ", capacity=" + capacity + ", birthday="
- + birthday + ", bookTypeName=" + bookTypeName + ", source=" + source + "]";
- }
- }
vo BookVo类
- package dozer;
- /**
- * @author zhuc
- * @create 2013-3-28 下午1:58:34
- */
- public class BookVo {
- private Integer id;
- private String nameVo;
- private String authorVo;
- private Integer capacity;
- private String day;
- private BookType bookType;
- private String source;
- /**
- * @return the nameVo
- */
- public String getNameVo() {
- return nameVo;
- }
- /**
- * @return the authorVo
- */
- public String getAuthorVo() {
- return authorVo;
- }
- /**
- * @param nameVo the nameVo to set
- */
- public void setNameVo(String nameVo) {
- this.nameVo = nameVo;
- }
- /**
- * @param authorVo the authorVo to set
- */
- public void setAuthorVo(String authorVo) {
- this.authorVo = authorVo;
- }
- /**
- * @return the capacity
- */
- public Integer getCapacity() {
- return capacity;
- }
- /**
- * @param capacity the capacity to set
- */
- public void setCapacity(Integer capacity) {
- this.capacity = capacity;
- }
- /**
- * @return the id
- */
- public Integer getId() {
- return id;
- }
- /**
- * @param id the id to set
- */
- public void setId(Integer id) {
- this.id = id;
- }
- /**
- * @return the day
- */
- public String getDay() {
- return day;
- }
- /**
- * @param day the day to set
- */
- public void setDay(String day) {
- this.day = day;
- }
- /**
- * @return the bookType
- */
- public BookType getBookType() {
- return bookType;
- }
- /**
- * @param bookType the bookType to set
- */
- public void setBookType(BookType bookType) {
- this.bookType = bookType;
- }
- /**
- * @return the source
- */
- public String getSource() {
- return source;
- }
- /**
- * @param source the source to set
- */
- public void setSource(String source) {
- this.source = source;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "BookVo [id=" + id + ", nameVo=" + nameVo + ", authorVo=" + authorVo + ", capacity=" + capacity
- + ", day=" + day + ", bookType=" + bookType + ", source=" + source + "]";
- }
- }
其中vo中包含复杂对象BookType类
- package dozer;
- /**
- * @author zhuc
- * @create 2013-3-28 下午2:43:16
- */
- public class BookType {
- private String name;
- private String desc;
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
- /**
- * @return the desc
- */
- public String getDesc() {
- return desc;
- }
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
- /**
- * @param desc the desc to set
- */
- public void setDesc(String desc) {
- this.desc = desc;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "BookType [name=" + name + ", desc=" + desc + "]";
- }
- }
这里在复制对象,我们发现有类型不一致、名称不一样或者都不一样的需要自定义映射的字段等,我们需要自定义mapping.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">
- <mapping date-format="yyyy-MM-dd HH:mm:ss">
- <class-a>dozer.Book</class-a>
- <class-b>dozer.BookVo</class-b>
- <field>
- <a>name</a>
- <b>nameVo</b>
- </field>
- <field>
- <a>author</a>
- <b>authorVo</b>
- </field>
- <field>
- <a>birthday</a>
- <b>day</b>
- </field>
- <field>
- <a>bookTypeName</a>
- <b>bookType.name</b>
- </field>
- <field custom-converter="dozer.MyCustomConverter">
- <a>source</a>
- <b>source</b>
- </field>
- </mapping>
- </mappings>
- package dozer;
- import org.dozer.CustomConverter;
- /**
- * 自定义转换类
- * @author zhuc
- * @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 instanceof Integer) {
- if (((Integer) sourceFieldValue).intValue() == 1900) {
- obj = "20世纪";
- } else if (((Integer) sourceFieldValue).intValue() == 2000) {
- obj = "21世纪";
- }
- } else if (sourceFieldValue instanceof String) {
- if ("20世纪".equals(sourceFieldValue)) {
- obj = 1900;
- } else if ("21世纪".equals(sourceFieldValue)) {
- obj = 2000;
- }
- }
- }
- return obj;
- }
- }
到这里,我们来看下真正的代码转换测试类:
- package dozer;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- import org.dozer.DozerBeanMapper;
- /**
- * @author zhuc
- * @create 2013-3-28 下午3:15:49
- */
- public class Test {
- /**
- * @param args
- */
- public static void main(String[] args) {
- List<String> mappers = new ArrayList<String>();
- mappers.add("mapper.xml");
- DozerBeanMapper dozer = new DozerBeanMapper();
- dozer.setMappingFiles(mappers);
- Book book = new Book();
- book.setId(100); // id 2个JavaBean一致
- book.setName("明天"); // Book:name(String) <-> BookVo:nameVo(String) 类型一致,名称不一致
- book.setAuthor("James"); // Book:author(String) <-> BookVo:authorVo(String) 类型一致,名称不一致
- book.setCapacity("123"); // Book:capacity(String) <-> BookVo:capacity(Integer) 类型不一致,名称一致
- book.setBirthday(new Date()); // Book:birthday(Date) <-> BookVo:day(String) 类型名称都不一致,且Date<->String互转
- book.setBookTypeName("科教类"); // Book:bookTypeName(String) <-> BookVo:BookType:name(String) 源类的字段映射为目标类的复杂对象的字段。
- book.setSource(1900); // Book:source(Integer) <-> BookVo:source(String) 自定义的转换,需要实现dozer的CustomConverter接口
- BookVo vo = new BookVo();
- dozer.map(book, vo);
- System.out.println(book);
- System.out.println(vo);
- }
- }
输出结果:
Book [id=100, name=明天, author=James, capacity=123, birthday=Thu Mar 28 16:00:20 CST 2013, bookTypeName=科教类, source=1900]
BookVo [id=100, nameVo=明天, authorVo=James, capacity=123, day=2013-03-28 16:00:20, bookType=BookType [name=科教类, desc=null], source=20世纪]