http://seyaa.iteye.com/blog/762494
1.1 什么是dozer?
Dozer 是一個對象轉換工具。
Dozer可以在JavaBean到JavaBean之間進行遞歸數據復制,并且這些JavaBean可以是不同的復雜的類型。
所有的mapping,Dozer將會很直接的將名稱相同的fields進行復制,如果field名不同,或者有特別的對應要求,則可以在xml中進行定義。
更多詳細請參考dozer官網:http://dozer.sourceforge.net/documentation/about.html
1.2 為什么要使用Dozer?
分析多層架構的J2EE系統,經常存在JavaBean直接的拷貝。比如我們在DAO層,通過Do取得業務層需要的數據,將這些數據傳遞給 Service層的VO。Do與VO就存在典型的值拷貝。
典型的解決方案就是手動拷貝,弊端很明顯,代碼中充斥大量Set 和Get方法,真正的業務被埋藏值與值的拷貝之中。另一種方案就是使用BeanUtil,但BeanUtil不夠很好的靈活性,又時候還不得不手動拷貝。Dozer可以靈活的對對象進行轉換,且使用簡單。
注意:Dozer支持簡單類型 復雜類型的雙向遞歸映射。
1.3 如何得到Dozer 工具類jar包
1.點擊下載:http://sourceforge.net/projects/dozer/files/
2.如果使用maven工具的話,在pom.Xml文件中加入:
Java代碼 ?
<dependency> ?? ????????<groupId>net.sf.dozer</groupId> ?? ????????<artifactId>dozer</artifactId> ?? ????????<version>5.2 .1 </version> ?? </dependency>?? <dependency><groupId>net.sf.dozer</groupId><artifactId>dozer</artifactId><version>5.2.1</version>
</dependency>
加入你的構建路徑既可以使用。
2 Dozer 支持的轉換類型
Dozer支持
Primitive 基本數據類型 , 后面帶 Wrapper 是包裝類 Complex Type 是復雜類型
? Primitive to Primitive Wrapper
? Primitive to Custom Wrapper
? Primitive Wrapper to Primitive Wrapper
? Primitive to Primitive
? Complex Type to Complex Type
? String to Primitive
? String to Primitive Wrapper
? String to Complex Type if the Complex Type contains a String constructor
? String 到復雜類型 , 如果復雜類型包含一個 String 類型的構造器
? String to Map
? Collection to Collection
? Collection to Array
? Map to Complex Type
? Map to Custom Map Type
? Enum to Enum
? Each of these can be mapped to one another: java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.util.Calendar, java.util.GregorianCalendar
? String to any of the supported Date/Calendar Objects.
? Objects containing a toString() method that produces a long representing time in (ms) to any supported Date/Calendar object.
3 Dozer使用(不與spring集成下)
3.1 dozer使用分類
根據有無映射文件和文件的多少,有三種方式:
第一種:該方式用于數據類型為基本類型,名稱相同的對象映射
Java代碼 ?
Mapper?mapper?=?new ?DozerBeanMapper(); ?? SourceObject?sourceObject?=?new ?SourceObject(); ?? DestinationObject?destObject?=?(DestinationObject)?mapper.map(sourceObject,?DestinationObject.class ); ?? ?????? DestinationObject?destObject?=?new ?DestinationObject(); ?? mapper.map(sourceObject,?destObject);?? Mapper mapper = new DozerBeanMapper();
SourceObject sourceObject = new SourceObject();
DestinationObject destObject = (DestinationObject) mapper.map(sourceObject, DestinationObject.class);// or
DestinationObject destObject = new DestinationObject();
mapper.map(sourceObject, destObject);
第二種:該方式用于數據類型不一致,或者名稱不相同或者有級聯關系等情況下的映射,該方式可以添加多個配置文件dozerBeanMapping.xml、someOtherDozerBeanMappings.xml 等
Java代碼 ?
List?myMappingFiles?=?new ?ArrayList(); ?? myMappingFiles.add("dozerBeanMapping.xml" ); ?? ?? DozerBeanMapper?mapper?=?new ?DozerBeanMapper(); ?? SourceObject?sourceObject?=?new ?SourceObject(); ?? mapper.setMappingFiles(myMappingFiles); ?? DestinationObject?stObject= ?? (DestinationObject)?mapper.map(sourceObject,?DestinationObject.class );?? List myMappingFiles = new ArrayList();
myMappingFiles.add("dozerBeanMapping.xml");
//myMappingFiles.add("someOtherDozerBeanMappings.xml");
DozerBeanMapper mapper = new DozerBeanMapper();
SourceObject sourceObject = new SourceObject();
mapper.setMappingFiles(myMappingFiles);
DestinationObject stObject=
(DestinationObject) mapper.map(sourceObject, DestinationObject.class);
第三種:該方式用于數據類型不一致,或者名稱不相同或者有級聯關系等情況下的映射,配置文件只有一個映射文件叫dozerBeanMapping.xml且在根目錄下
Java代碼 ?
Mapper?mapper?=?DozerBeanMapperSingletonWrapper.getInstance(); ?? SourceObject?sourceObject?=?new ?SourceObject(); ?? DestinationObject?destObject?=?(DestinationObject)?mapper.map(sourceObject,?DestinationObject.class ); ?? ?? ?? ?? mapper.map(sourceObject,?destObject);?? Mapper mapper = DozerBeanMapperSingletonWrapper.getInstance();
SourceObject sourceObject = new SourceObject();
DestinationObject destObject = (DestinationObject) mapper.map(sourceObject, DestinationObject.class);
//or
//Mapper mapper = DozerBeanMapperSingletonWrapper.getInstance();
//DestinationObject destObject = new DestinationObject();
mapper.map(sourceObject, destObject);
3.2 舉例說明:
假設我們現在有一個userDo類,如下:
Java代碼 ?
package ?ce.dozer; ??public ?class ?User?{ ??????private ?int ?id; ?? ????private ?String?name; ?? ????private ?String?password; ?? ????private ?Info?info; ?? ????public ?int ?getId()?{ ?? ????????return ?id; ?? ????} ?? ????public ?void ?setId(int ?id)?{ ?? ????????this .id?=?id; ?? ????} ?? ????public ?String?getName()?{ ?? ????????return ?name; ?? ????} ?? ????public ?void ?setName(String?name)?{ ?? ????????this .name?=?name; ?? ????} ?? ????public ?String?getPassword()?{ ?? ????????return ?password; ?? ????} ?? ????public ?void ?setPassword(String?password)?{ ?? ????????this .password?=?password; ?? ????} ?? ????public ?Info?getInfo()?{ ?? ????????return ?info; ?? ????} ?? ????public ?void ?setInfo(Info?info)?{ ?? ????????this .info?=?info; ?? ????} ?? }?? package ce.dozer;
public class User {private int id;private String name;private String password;private Info info;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Info getInfo() {return info;}public void setInfo(Info info) {this.info = info;}
}
一個userVo類,如下:
Java代碼 ?
package ?ce.dozer; ??public ?class ?UserVO?{ ??????private ?int ?id; ?? ????private ?String?userName; ?? ????private ?String?password; ?? ????private ?InfoVO?info; ?? ????public ?int ?getId()?{ ?? ????????return ?id; ?? ????} ?? ????public ?void ?setId(int ?id)?{ ?? ????????this .id?=?id; ?? ????} ?? ????public ?String?getUserName()?{ ?? ????????return ?userName; ?? ????} ?? ????public ?void ?setUserName(String?userName)?{ ?? ????????this .userName?=?userName; ?? ????} ?? ????public ?String?getPassword()?{ ?? ????????return ?password; ?? ????} ?? ????public ?void ?setPassword(String?password)?{ ?? ????????this .password?=?password; ?? ????} ?? ????public ?InfoVO?getInfo()?{ ?? ????????return ?info; ?? ????} ?? ????public ?void ?setInfo(InfoVO?info)?{ ?? ????????this .info?=?info; ?? ????} ?? }?? package ce.dozer;
public class UserVO {private int id;private String userName;private String password;private InfoVO info;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public InfoVO getInfo() {return info;}public void setInfo(InfoVO info) {this.info = info;}
}
一個性別枚舉類,如下:
Java代碼 ?
package ?ce.dozer; ??public ?enum ?GenderType?{ ??????male,?? ????female?? }?? package ce.dozer;
public enum GenderType {male,//男female//女
}
一個infoDo類,如下:
Java代碼 ?
package ?ce.dozer; ??import ?java.util.Date; ??public ?class ?Info?{ ??????private ?int ?id; ?? ????private ?Date?createDate; ?? ????private ?GenderType?gender; ?? ????public ?int ?getId()?{ ?? ????????return ?id; ?? ????} ?? ????public ?void ?setId(int ?id)?{ ?? ????????this .id?=?id; ?? ????} ?? ????public ?Date?getCreateDate()?{ ?? ????????return ?createDate; ?? ????} ?? ????public ?void ?setCreateDate(Date?createDate)?{ ?? ????????this .createDate?=?createDate; ?? ????} ?? ????public ?GenderType?getGender()?{ ?? ????????return ?gender; ?? ????} ?? ????public ?void ?setGender(GenderType?gender)?{ ?? ????????this .gender?=?gender; ?? ????} ?? }?? package ce.dozer;
import java.util.Date;
public class Info {private int id;private Date createDate;private GenderType gender;public int getId() {return id;}public void setId(int id) {this.id = id;}public Date getCreateDate() {return createDate;}public void setCreateDate(Date createDate) {this.createDate = createDate;}public GenderType getGender() {return gender;}public void setGender(GenderType gender) {this.gender = gender;}
}
一個infoVo類,如下:
Java代碼 ?
package ?ce.dozer; ??public ?class ?InfoVO?{ ??????private ?int ?id; ?? ????private ?String?date; ?? ????private ?Integer?gender; ?? ????public ?int ?getId()?{ ?? ????????return ?id; ?? ????} ?? ????public ?void ?setId(int ?id)?{ ?? ????????this .id?=?id; ?? ????} ?? ????public ?String?getDate()?{ ?? ????????return ?date; ?? ????} ?? ????public ?void ?setDate(String?date)?{ ?? ????????this .date?=?date; ?? ????} ?? ????public ?Integer?getGender()?{ ?? ????????return ?gender; ?? ????} ?? ????public ?void ?setGender(Integer?gender)?{ ?? ????????this .gender?=?gender; ?? ????} ?? }?? package ce.dozer;
public class InfoVO {private int id;private String date;private Integer gender;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public Integer getGender() {return gender;}public void setGender(Integer gender) {this.gender = gender;}
}
在給出的示例中我們可以看到userDo與 userVo 中的字段對應關系
userVo userDo 不同
id(int) id(int)
userName(String) name(String) 名稱不同
password(String) password(String)
Info(InfoVo) info (Info) 類型不同
再看看infoDo與 infoVo 中的字段對應關系
infoVo infoDo 不同
id(int) Id(int)
createDate(String) date(Date) 類型不同
gender(Integer) Gender(GenderType)枚舉 類型不同
綜合上面的問題我們可以如下解決方式:
3.2.1 字段名稱不同映射配置
Java代碼 ?
<mapping> ?? ????????<class -a>ce.dozer.User</class -a> ?? ????????<class -b>ce.dozer.UserVO</class -b> ?? ????????<field> ?? ????????????<a>name</a> ?? ????????????<b>userName</b> ?? ????????</field> ?? </mapping>?? <mapping><class-a>ce.dozer.User</class-a><class-b>ce.dozer.UserVO</class-b><field><a>name</a><b>userName</b></field>
</mapping>
3.2.2 Date與String映射配置如下:
Java代碼 ?
<mapping?date-format="yyyy-MM-dd" > ?? ????????<class -a>ce.dozer.User</class -a> ?? ????????<class -b>ce.dozer.UserVO</class -b> ?? ????????<field> ?? ????????????<a>info.createDate</a> ?? ????????????<b>info.date</b> ?? ????????</field> ?? </mapping>?? <mapping date-format="yyyy-MM-dd"><class-a>ce.dozer.User</class-a><class-b>ce.dozer.UserVO</class-b><field><a>info.createDate</a><b>info.date</b></field>
</mapping>
3.2.3 在示例中我們看到在userDo和userVo對象中關聯了其他的對象,這個問題不用擔心,因為對象名稱相同dozer會為我們自動轉換。而問題不在這,在與對象中有枚舉類型,我們該怎么寫配置呢?在這里我們就必須自己編寫一個處理類來處理枚舉與Integer的轉換了(假設我們的處理類為util.EnumIntConverter),配置如下:
Java代碼 ?
<configuration> ?? ????<stop-on-errors>true </stop-on-errors> ?? ????<date-format>yyyy-MM-dd</date-format> ?? ????<wildcard>true </wildcard> ?? ????<custom-converters>? ?? ????????<converter?type="?util.EnumIntConverter" > ?? ????????????<class -a>java.lang.Enum</class -a> ?? ????????????<class -b>java.lang.Integer</class -b> ?? ????????</converter> ?? ????</custom-converters> ?? </configuration> ?? <mapping> ?? ????<class -a>ce.dozer.User</class -a> ?? ????<class -b>ce.dozer.UserVO</class -b> ?? ????<field> ?? ????????<a>info.gender</a> ?? ????????<b>info.gender</b> ?? ????</field> ?? </mapping>?? <configuration><stop-on-errors>true</stop-on-errors><date-format>yyyy-MM-dd</date-format><wildcard>true</wildcard><custom-converters> <converter type=" util.EnumIntConverter"><class-a>java.lang.Enum</class-a><class-b>java.lang.Integer</class-b></converter></custom-converters>
</configuration>
<mapping><class-a>ce.dozer.User</class-a><class-b>ce.dozer.UserVO</class-b><field><a>info.gender</a><b>info.gender</b></field>
</mapping>
最終的dozerBeanMapping.xml 配置文件:
Java代碼 ?
<?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:?? ??????????http:?? ?? ????<configuration> ?? ????????<stop-on-errors>true </stop-on-errors> ?? ????????<date-format>yyyy-MM-dd</date-format> ?? ????????<wildcard>true </wildcard> ?? ????????<custom-converters> ?? ????????????<converter?type="?util.EnumIntConverter" > ?? ????????????????<class -a>java.lang.Enum</class -a> ?? ????????????????<class -b>java.lang.Integer</class -b> ?? ????????????</converter> ?? ????????</custom-converters> ?? ????</configuration> ?? ????<mapping?date-format="yyyy-MM-dd" > ?? ????????<class -a>ce.dozer.User</class -a> ?? ????????<class -b>ce.dozer.UserVO</class -b> ?? ????????<field> ?? ????????????<a>info.createDate</a> ?? ????????????<b>info.date</b> ?? ????????</field> ?? ????????<field> ?? ????????????<a>info.gender</a> ?? ????????????<b>info.gender</b> ?? ????????</field> ?? ????????<field> ?? ????????????<a>info.createDate</a> ?? ????????????<b>info.date</b> ?? ????????</field> ?? ????????<field> ?? ????????????<a>name</a> ?? ????????????<b>userName</b> ?? ????????</field> ?? ????</mapping> ?? </mappings>?? <?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.nethttp://dozer.sourceforge.net/schema/beanmapping.xsd"><configuration><stop-on-errors>true</stop-on-errors><date-format>yyyy-MM-dd</date-format><wildcard>true</wildcard><custom-converters><converter type=" util.EnumIntConverter"><class-a>java.lang.Enum</class-a><class-b>java.lang.Integer</class-b></converter></custom-converters></configuration><mapping date-format="yyyy-MM-dd"><class-a>ce.dozer.User</class-a><class-b>ce.dozer.UserVO</class-b><field><a>info.createDate</a><b>info.date</b></field><field><a>info.gender</a><b>info.gender</b></field><field><a>info.createDate</a><b>info.date</b></field><field><a>name</a><b>userName</b></field></mapping>
</mappings>
4 與spring的集成
4.1 1、dozer 要與spring集成需要將dozer交給spring管理,配置如下:
Xml代碼 ?
<? 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-2.0.xsd ?? ????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.0.xsd ?? ????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.0.xsd" ?? ????default-autowire ="byName" ?default-lazy-init ="false" > ?? ?? ????< bean ?id ="mapper" ?class ="org.dozer.spring.DozerBeanMapperFactoryBean" > ?? ????????< property ?name ="mappingFiles" > ?? < list > ?????????????< value > classpath*:dozer-config/dozerBeanMapping.xml</ value > ??????????????</ list > ?? ????????</ property > ?? ????</ bean > ?? </ beans > ??? <?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-2.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"default-autowire="byName" default-lazy-init="false"><bean id="mapper" class="org.dozer.spring.DozerBeanMapperFactoryBean"><property name="mappingFiles">
<list> <value>classpath*:dozer-config/dozerBeanMapping.xml</value></list></property></bean>
</beans>
4.2 2、當我們的dozer交給了spring管理,當spring容器啟動后我們可以將下面的代碼添加到用于繼承的基類中去:
Java代碼 ?
private ?Mapper?mapper?; ??public ?Mapper?getMapper()?{ ??????return ?mapper; ?? } ?? public ?void ?setMapper(Mapper?mapper)?{ ??????this .mapper?=?mapper; ?? } ?? 4.3 ?3 、在繼承者類中就可以直接如下使用: ??getMapper().map(sourceObject,?DestinationObject.class )?? private Mapper mapper ;
public Mapper getMapper() {return mapper;
}
public void setMapper(Mapper mapper) {this.mapper = mapper;
}
4.3 3、在繼承者類中就可以直接如下使用:
getMapper().map(sourceObject, DestinationObject.class)
5 結束語
Dozer的轉換功能很強大,我們所能想到的類型轉換,它基本都可以幫助我們完成。所以如果您想對dozer了解更多更深,建議到官網仔細閱讀相關文檔和說明!
官網:http://dozer.sourceforge.net/documentation/mappings.html
示例代碼.rar (1.9 KB) 下載次數: 57
?
總結
以上是生活随笔 為你收集整理的Dozer 使用总结 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。