一、简介
分析多层架构的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文中加入:
net.sf.dozer dozer 5.4.0
三、示例
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 映射文件。
dozer.Book dozer.BookVo name nameVo author authorVo birthday day bookTypeName bookType.name source source
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 mappers = new ArrayList();
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世纪]