- 浏览: 7948094 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
http://www.cnblogs.com/jingmoxukong/p/5952447.html
将Dozer引入到工程中后,我们就可以来小试一番了。
实践出真知,先以一个最简单的例子来展示Dozer映射的处理过程。
准备
我们先准备两个要互相映射的类
NotSameAttributeA.java
public class NotSameAttributeA {
private long id;
private String name;
private Date date;
// 省略getter/setter
}
NotSameAttributeB.java
public class NotSameAttributeB {
private long id;
private String value;
private Date date;
// 省略getter/setter
}
这两个类存在属性名不完全相同的情况:name 和 value。
Dozer的配置
为什么要有映射配置?
如果要映射的两个对象有完全相同的属性名,那么一切都很简单。
只需要直接使用Dozer的API即可:
Mapper mapper = new DozerBeanMapper();
DestinationObject destObject =
mapper.map(sourceObject, DestinationObject.class);
但实际映射时,往往存在属性名不同的情况。
所以,你需要一些配置来告诉Dozer应该转换什么,怎么转换。
注:官网着重建议:在现实应用中,最好不要每次映射对象时都创建一个Mapper实例来工作,这样会产生不必要的开销。如果你不使用IoC容器(如:spring)来管理你的项目,那么,最好将Mapper定义为单例模式。
映射配置文件
在src/test/resources目录下添加dozer/dozer-mapping.xml文件。
<mapping>标签中允许你定义<class-a>和<class-b>,对应着相互映射的类。
<field>标签里定义要映射的特殊属性。需要注意<a>和<class-a>对应,<b>和<class-b>对应,聪明的你,猜也猜出来了吧。
<?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">
<class-a>org.zp.notes.spring.common.dozer.vo.NotSameAttributeA</class-a>
<class-b>org.zp.notes.spring.common.dozer.vo.NotSameAttributeB</class-b>
<field>
<a>name</a>
<b>value</b>
</field>
</mapping>
</mappings>
与Spring整合
配置DozerBeanMapperFactoryBean
在src/test/resources目录下添加spring/spring-dozer.xml文件。
Dozer与Spring的整合很便利,你只需要声明一个DozerBeanMapperFactoryBean,
将所有的dozer映射配置文件作为属性注入到mappingFiles,DozerBeanMapperFactoryBean会加载这些规则。
spring-dozer.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/dozer-mapping.xml</value>
</list>
</property>
</bean>
</beans>
自动装配
至此,万事具备,你只需要自动装配mapper。
RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/spring-dozer.xml"})
@TransactionConfiguration(defaultRollback = false)
public class DozerTest extends TestCase {
@Autowired
Mapper mapper;
@Test
public void testNotSameAttributeMapping() {
NotSameAttributeA src = new NotSameAttributeA();
src.setId(007);
src.setName("邦德");
src.setDate(new Date());
NotSameAttributeB desc = mapper.map(src, NotSameAttributeB.class);
Assert.assertNotNull(desc);
}
}
运行一下单元测试,绿灯通过。
回到顶部
Dozer支持的数据类型转换
Dozer可以自动做数据类型转换。当前,Dozer支持以下数据类型转换(都是双向的)
Primitive to Primitive Wrapper
原型(int、long等)和原型包装类(Integer、Long)
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 to Map
字符串和Map
Collection to Collection
集合和集合
Collection to Array
集合和数组
Map to Complex Type
Map和复杂类型
Map to Custom Map Type
Map和定制Map类型
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
这些时间相关的常见类可以互换: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.
字符串和支持Date/Calendar的对象
Objects containing a toString() method that produces a long representing time in (ms) to any supported Date/Calendar object.
如果一个对象的toString()方法返回的是一个代表long型的时间数值(单位:ms),就可以和任何支持Date/Calendar的对象转换。
回到顶部
Dozer的映射配置
在前面的简单例子中,我们体验了一把Dozer的映射流程。但是两个类进行映射,有很多复杂的情况,相应的,你也需要一些更复杂的配置。
Dozer有三种映射配置方式:
注解方式
API方式
XML方式
用注解来配置映射
Dozer 5.3.2版本开始支持注解方式配置映射(只有一个注解:@Mapping)。可以应对一些简单的映射处理,复杂的就玩不转了。
看一下@Mapping的声明就可以知道,这个注解只能用于元素和方法。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Mapping {
String value() default "";
}
让我们来试试吧:
TargetBean.java
public class SourceBean {
private Long id;
private String name;
@Mapping("binaryData")
private String data;
@Mapping("pk")
public Long getId() {
return this.id;
}
//其余getter/setter方法略
}
TargetBean.java
public class TargetBean {
private String pk;
private String name;
private String binaryData;
//getter/setter方法略
}
定义了两个相互映射的Java类,只需要在源类中用@Mapping标记和目标类中对应的属性就可以了。
@Test
public void testAnnotationMapping() {
SourceBean src = new SourceBean();
src.setId(7L);
src.setName("邦德");
src.setData("00000111");
TargetBean desc = mapper.map(src, TargetBean.class);
Assert.assertNotNull(desc);
}
测试一下,绿灯通过。
官方文档说,虽然当前版本(文档的版本对应Dozer 5.5.1)仅支持@Mapping,但是在未来的发布版本会提供其他的注解功能,那就敬请期待吧(再次吐槽一下:一年多没更新了)。
用API来配置映射
个人觉得这种方式比较麻烦,不推荐,也不想多做介绍,就是这么任性。
用XML来配置映射
需要强调的是:如果两个类的所有属性都能很好的互转,可以你中有我,我中有你,不分彼此,那么就不要画蛇添足的在xml中去声明映射规则了。
属性名不同时的映射(Basic Property Mapping)
Dozer会自动映射属性名相同的属性,所以不必添加在xml文件中。
<field>
<a>one</a>
<b>onePrime</b>
</field>
字符串和日期映射(String to Date Mapping)
字符串在和日期进行映射时,允许用户指定日期的格式。
格式的设置分为三个作用域级别:
属性级别
对当前属性有效(这个属性必须是日期字符串)
<field>
<a date-format="MM/dd/yyyy HH:mm:ss:SS">dateString</a>
<b>dateObject</b>
</field>
类级别
对这个类中的所有日期相关的属性有效
<mapping date-format="MM-dd-yyyy HH:mm:ss">
<class-a>org.dozer.vo.TestObject</class-a>
<class-b>org.dozer.vo.TestObjectPrime</class-b>
<field>
<a>dateString</a>
<b>dateObject</b>
</field>
</mapping>
全局级别
对整个文件中的所有日期相关的属性有效。
<mappings>
<configuration>
<date-format>MM/dd/yyyy HH:mm</date-format>
</configuration>
<mapping wildcard="true">
<class-a>org.dozer.vo.TestObject</class-a>
<class-b>org.dozer.vo.TestObjectPrime</class-b>
<field>
<a>dateString</a>
<b>dateObject</b>
</field>
</mapping>
</mappings>
集合和数组映射(Collection and Array Mapping)
Dozer可以自动处理以下类型的双向转换。
List to List
List to Array
Array to Array
Set to Set
Set to Array
Set to List
使用hint
如果使用泛型或数组,没有必要使用hint。
如果不使用泛型或数组。在处理集合或数组之间的转换时,你需要用hint指定目标列表的数据类型。
若你不指定hint,Dozer将认为目标集合和源集合的类型是一致的。
使用Hints的范例:
<field>
<a>hintList</a>
<b>hintList</b>
<b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint>
</field>
累计映射和非累计映射(Cumulative vs. Non-Cumulative List Mapping)
如果你要转换的目标类已经初始化,你可以选择让Dozer添加或更新对象到你的集合中。
而这取决于relationship-type配置,默认是累计。
它的设置有作用域级别:
全局级
<mappings>
<configuration>
<relationship-type>non-cumulative</relationship-type>
</configuration>
</mappings>
类级别
<mappings>
<mapping relationship-type="non-cumulative">
<!-- 省略 -->
</mapping>
</mappings>
属性级别
<field relationship-type="cumulative">
<a>hintList</a>
<b>hintList</b>
<a-hint>org.dozer.vo.TheFirstSubClass</a-hint>
<b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint>
</field>
移动孤儿(Removing Orphans)
这里的孤儿是指目标集合中存在,但是源集合中不存在的元素。
你可以使用remove-orphans开关来选择是否移除这样的元素。
<field remove-orphans="true">
<a>srcList</a>
<b>destList</b>
</field>
深度映射(Deep Mapping)
所谓深度映射,是指允许你指定属性的属性(比如一个类的属性本身也是一个类)。
举例来说
Source.java
public class Source {
private long id;
private String info;
}
Dest.java
public class Dest {
private long id;
private Info info;
}
public class Info {
private String content;
}
映射规则
<mapping>
<class-a>org.zp.notes.spring.common.dozer.vo.Source</class-a>
<class-b>org.zp.notes.spring.common.dozer.vo.Dest</class-b>
<field>
<a>info</a>
<b>info.content</b>
</field>
</mapping>
排除属性(Excluding Fields)
就像任何团体都有捣乱分子,类之间转换时也有想要排除的因子。
如何在做类型转换时,自动排除一些属性,Dozer提供了几种方法,这里只介绍一种比较通用的方法。
更多详情参考官网。
field-exclude可以排除不需要映射的属性。
<field-exclude>
<a>fieldToExclude</a>
<b>fieldToExclude</b>
</field-exclude>
单向映射(One-Way Mapping)
注:本文的映射方式,无特殊说明,都是双向映射的。
有的场景可能希望转换过程不可逆,即单向转换。
单向转换可以通过使用one-way来开启
类级别
<mapping type="one-way">
<class-a>org.dozer.vo.TestObjectFoo</class-a>
<class-b>org.dozer.vo.TestObjectFooPrime</class-b>
<field>
<a>oneFoo</a>
<b>oneFooPrime</b>
</field>
</mapping>
属性级别
<mapping>
<class-a>org.dozer.vo.TestObjectFoo2</class-a>
<class-b>org.dozer.vo.TestObjectFooPrime2</class-b>
<field type="one-way">
<a>oneFoo2</a>
<b>oneFooPrime2</b>
</field>
<field type="one-way">
<a>oneFoo3.prime</a>
<b>oneFooPrime3</b>
</field>
全局配置(Global Configuration)
全局配置用来设置全局的配置信息。此外,任何定制转换都是在这里定义的。
全局配置都是可选的。
<date-format>表示日期格式
<stop-on-errors>错误处理开关
<wildcard>通配符
<trim-strings>裁剪字符串开关
<configuration >
<date-format>MM/dd/yyyy HH:mm</date-format>
<stop-on-errors>true</stop-on-errors>
<wildcard>true</wildcard>
<trim-strings>false</trim-strings>
<custom-converters> <!-- these are always bi-directional -->
<converter type="org.dozer.converters.TestCustomConverter" >
<class-a>org.dozer.vo.TestCustomConverterObject</class-a>
<class-b>another.type.to.Associate</class-b>
</converter>
</custom-converters>
</configuration>
全局配置的作用是帮助你少配置一些参数,如果个别类的映射规则需要变更,你可以mapping中覆盖它。
覆盖的范例如下
<mapping date-format="MM-dd-yyyy HH:mm:ss">
<!-- 省略 -->
</mapping>
<mapping wildcard="false">
<!-- 省略 -->
</mapping>
<mapping stop-on-errors="false">
<!-- 省略 -->
</mapping>
<mapping trim-strings="true">
<!-- 省略 -->
</mapping>
定制转换(Custom Converters)
如果Dozer默认的转换规则不能满足实际需要,你可以选择定制转换。
定制转换通过配置XML来告诉Dozer如何去转换两个指定的类。当Dozer转换这两个指定类的时候,会调用你的映射规则去替换标准映射规则。
为了让Dozer识别,你必须实现org.dozer.CustomConverter接口。否则,Dozer会抛异常。
具体做法:
(1) 创建一个类实现org.dozer.CustomConverter接口。
public class TestCustomConverter implements CustomConverter {
public Object convert(Object destination, Object source,
Class destClass, Class sourceClass) {
if (source == null) {
return null;
}
CustomDoubleObject dest = null;
if (source instanceof Double) {
// check to see if the object already exists
if (destination == null) {
dest = new CustomDoubleObject();
} else {
dest = (CustomDoubleObject) destination;
}
dest.setTheDouble(((Double) source).doubleValue());
return dest;
} else if (source instanceof CustomDoubleObject) {
double sourceObj =
((CustomDoubleObject) source).getTheDouble();
return new Double(sourceObj);
} else {
throw new MappingException("Converter TestCustomConverter "
+ "used incorrectly. Arguments passed in were:"
+ destination + " and " + source);
}
}
(2) 在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">
<configuration>
<!-- 总是双向转换的 -->
<custom-converters>
<converter type="org.dozer.converters.TestCustomConverter" >
<class-a>org.dozer.vo.CustomDoubleObject</class-a>
<class-b>java.lang.Double</class-b>
</converter>
<!-- You are responsible for mapping everything between
ClassA and ClassB -->
<converter
type="org.dozer.converters.TestCustomHashMapConverter" >
<class-a>org.dozer.vo.TestCustomConverterHashMapObject</class-a>
<class-b>org.dozer.vo.TestCustomConverterHashMapPrimeObject</class-b>
</converter>
</custom-converters>
</configuration>
</mappings>
属性级
<mapping>
<class-a>org.dozer.vo.SimpleObj</class-a>
<class-b>org.dozer.vo.SimpleObjPrime2</class-b>
<field custom-converter=
"org.dozer.converters.TestCustomConverter">
<a>field1</a>
<b>field1Prime</b>
</field>
</mapping>
映射的继承(Inheritance Mapping)
Dozer支持映射规则的继承机制。
属性如果有着相同的名字则不需要在xml中配置,除非使用了hint
我们来看一个例子
<mapping>
<class-a>org.dozer.vo.SuperClass</class-a>
<class-b>org.dozer.vo.SuperClassPrime</class-b>
<field>
<a>superAttribute</a>
<b>superAttr</b>
</field>
</mapping>
<mapping>
<class-a>org.dozer.vo.SubClass</class-a>
<class-b>org.dozer.vo.SubClassPrime</class-b>
<field>
<a>attribute</a>
<b>attributePrime</b>
</field>
</mapping>
<mapping>
<class-a>org.dozer.vo.SubClass2</class-a>
<class-b>org.dozer.vo.SubClassPrime2</class-b>
<field>
<a>attribute2</a>
<b>attributePrime2</b>
</field>
</mapping>
在上面的例子中SubClass、SubClass2是SuperClass的子类;
SubClassPrime和SubClassPrime2是SuperClassPrime的子类。
superAttribute和superAttr的映射规则会被子类所继承,所以不必再重复的在子类中去声明。
将Dozer引入到工程中后,我们就可以来小试一番了。
实践出真知,先以一个最简单的例子来展示Dozer映射的处理过程。
准备
我们先准备两个要互相映射的类
NotSameAttributeA.java
public class NotSameAttributeA {
private long id;
private String name;
private Date date;
// 省略getter/setter
}
NotSameAttributeB.java
public class NotSameAttributeB {
private long id;
private String value;
private Date date;
// 省略getter/setter
}
这两个类存在属性名不完全相同的情况:name 和 value。
Dozer的配置
为什么要有映射配置?
如果要映射的两个对象有完全相同的属性名,那么一切都很简单。
只需要直接使用Dozer的API即可:
Mapper mapper = new DozerBeanMapper();
DestinationObject destObject =
mapper.map(sourceObject, DestinationObject.class);
但实际映射时,往往存在属性名不同的情况。
所以,你需要一些配置来告诉Dozer应该转换什么,怎么转换。
注:官网着重建议:在现实应用中,最好不要每次映射对象时都创建一个Mapper实例来工作,这样会产生不必要的开销。如果你不使用IoC容器(如:spring)来管理你的项目,那么,最好将Mapper定义为单例模式。
映射配置文件
在src/test/resources目录下添加dozer/dozer-mapping.xml文件。
<mapping>标签中允许你定义<class-a>和<class-b>,对应着相互映射的类。
<field>标签里定义要映射的特殊属性。需要注意<a>和<class-a>对应,<b>和<class-b>对应,聪明的你,猜也猜出来了吧。
<?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">
<class-a>org.zp.notes.spring.common.dozer.vo.NotSameAttributeA</class-a>
<class-b>org.zp.notes.spring.common.dozer.vo.NotSameAttributeB</class-b>
<field>
<a>name</a>
<b>value</b>
</field>
</mapping>
</mappings>
与Spring整合
配置DozerBeanMapperFactoryBean
在src/test/resources目录下添加spring/spring-dozer.xml文件。
Dozer与Spring的整合很便利,你只需要声明一个DozerBeanMapperFactoryBean,
将所有的dozer映射配置文件作为属性注入到mappingFiles,DozerBeanMapperFactoryBean会加载这些规则。
spring-dozer.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/dozer-mapping.xml</value>
</list>
</property>
</bean>
</beans>
自动装配
至此,万事具备,你只需要自动装配mapper。
RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/spring-dozer.xml"})
@TransactionConfiguration(defaultRollback = false)
public class DozerTest extends TestCase {
@Autowired
Mapper mapper;
@Test
public void testNotSameAttributeMapping() {
NotSameAttributeA src = new NotSameAttributeA();
src.setId(007);
src.setName("邦德");
src.setDate(new Date());
NotSameAttributeB desc = mapper.map(src, NotSameAttributeB.class);
Assert.assertNotNull(desc);
}
}
运行一下单元测试,绿灯通过。
回到顶部
Dozer支持的数据类型转换
Dozer可以自动做数据类型转换。当前,Dozer支持以下数据类型转换(都是双向的)
Primitive to Primitive Wrapper
原型(int、long等)和原型包装类(Integer、Long)
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 to Map
字符串和Map
Collection to Collection
集合和集合
Collection to Array
集合和数组
Map to Complex Type
Map和复杂类型
Map to Custom Map Type
Map和定制Map类型
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
这些时间相关的常见类可以互换: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.
字符串和支持Date/Calendar的对象
Objects containing a toString() method that produces a long representing time in (ms) to any supported Date/Calendar object.
如果一个对象的toString()方法返回的是一个代表long型的时间数值(单位:ms),就可以和任何支持Date/Calendar的对象转换。
回到顶部
Dozer的映射配置
在前面的简单例子中,我们体验了一把Dozer的映射流程。但是两个类进行映射,有很多复杂的情况,相应的,你也需要一些更复杂的配置。
Dozer有三种映射配置方式:
注解方式
API方式
XML方式
用注解来配置映射
Dozer 5.3.2版本开始支持注解方式配置映射(只有一个注解:@Mapping)。可以应对一些简单的映射处理,复杂的就玩不转了。
看一下@Mapping的声明就可以知道,这个注解只能用于元素和方法。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Mapping {
String value() default "";
}
让我们来试试吧:
TargetBean.java
public class SourceBean {
private Long id;
private String name;
@Mapping("binaryData")
private String data;
@Mapping("pk")
public Long getId() {
return this.id;
}
//其余getter/setter方法略
}
TargetBean.java
public class TargetBean {
private String pk;
private String name;
private String binaryData;
//getter/setter方法略
}
定义了两个相互映射的Java类,只需要在源类中用@Mapping标记和目标类中对应的属性就可以了。
@Test
public void testAnnotationMapping() {
SourceBean src = new SourceBean();
src.setId(7L);
src.setName("邦德");
src.setData("00000111");
TargetBean desc = mapper.map(src, TargetBean.class);
Assert.assertNotNull(desc);
}
测试一下,绿灯通过。
官方文档说,虽然当前版本(文档的版本对应Dozer 5.5.1)仅支持@Mapping,但是在未来的发布版本会提供其他的注解功能,那就敬请期待吧(再次吐槽一下:一年多没更新了)。
用API来配置映射
个人觉得这种方式比较麻烦,不推荐,也不想多做介绍,就是这么任性。
用XML来配置映射
需要强调的是:如果两个类的所有属性都能很好的互转,可以你中有我,我中有你,不分彼此,那么就不要画蛇添足的在xml中去声明映射规则了。
属性名不同时的映射(Basic Property Mapping)
Dozer会自动映射属性名相同的属性,所以不必添加在xml文件中。
<field>
<a>one</a>
<b>onePrime</b>
</field>
字符串和日期映射(String to Date Mapping)
字符串在和日期进行映射时,允许用户指定日期的格式。
格式的设置分为三个作用域级别:
属性级别
对当前属性有效(这个属性必须是日期字符串)
<field>
<a date-format="MM/dd/yyyy HH:mm:ss:SS">dateString</a>
<b>dateObject</b>
</field>
类级别
对这个类中的所有日期相关的属性有效
<mapping date-format="MM-dd-yyyy HH:mm:ss">
<class-a>org.dozer.vo.TestObject</class-a>
<class-b>org.dozer.vo.TestObjectPrime</class-b>
<field>
<a>dateString</a>
<b>dateObject</b>
</field>
</mapping>
全局级别
对整个文件中的所有日期相关的属性有效。
<mappings>
<configuration>
<date-format>MM/dd/yyyy HH:mm</date-format>
</configuration>
<mapping wildcard="true">
<class-a>org.dozer.vo.TestObject</class-a>
<class-b>org.dozer.vo.TestObjectPrime</class-b>
<field>
<a>dateString</a>
<b>dateObject</b>
</field>
</mapping>
</mappings>
集合和数组映射(Collection and Array Mapping)
Dozer可以自动处理以下类型的双向转换。
List to List
List to Array
Array to Array
Set to Set
Set to Array
Set to List
使用hint
如果使用泛型或数组,没有必要使用hint。
如果不使用泛型或数组。在处理集合或数组之间的转换时,你需要用hint指定目标列表的数据类型。
若你不指定hint,Dozer将认为目标集合和源集合的类型是一致的。
使用Hints的范例:
<field>
<a>hintList</a>
<b>hintList</b>
<b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint>
</field>
累计映射和非累计映射(Cumulative vs. Non-Cumulative List Mapping)
如果你要转换的目标类已经初始化,你可以选择让Dozer添加或更新对象到你的集合中。
而这取决于relationship-type配置,默认是累计。
它的设置有作用域级别:
全局级
<mappings>
<configuration>
<relationship-type>non-cumulative</relationship-type>
</configuration>
</mappings>
类级别
<mappings>
<mapping relationship-type="non-cumulative">
<!-- 省略 -->
</mapping>
</mappings>
属性级别
<field relationship-type="cumulative">
<a>hintList</a>
<b>hintList</b>
<a-hint>org.dozer.vo.TheFirstSubClass</a-hint>
<b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint>
</field>
移动孤儿(Removing Orphans)
这里的孤儿是指目标集合中存在,但是源集合中不存在的元素。
你可以使用remove-orphans开关来选择是否移除这样的元素。
<field remove-orphans="true">
<a>srcList</a>
<b>destList</b>
</field>
深度映射(Deep Mapping)
所谓深度映射,是指允许你指定属性的属性(比如一个类的属性本身也是一个类)。
举例来说
Source.java
public class Source {
private long id;
private String info;
}
Dest.java
public class Dest {
private long id;
private Info info;
}
public class Info {
private String content;
}
映射规则
<mapping>
<class-a>org.zp.notes.spring.common.dozer.vo.Source</class-a>
<class-b>org.zp.notes.spring.common.dozer.vo.Dest</class-b>
<field>
<a>info</a>
<b>info.content</b>
</field>
</mapping>
排除属性(Excluding Fields)
就像任何团体都有捣乱分子,类之间转换时也有想要排除的因子。
如何在做类型转换时,自动排除一些属性,Dozer提供了几种方法,这里只介绍一种比较通用的方法。
更多详情参考官网。
field-exclude可以排除不需要映射的属性。
<field-exclude>
<a>fieldToExclude</a>
<b>fieldToExclude</b>
</field-exclude>
单向映射(One-Way Mapping)
注:本文的映射方式,无特殊说明,都是双向映射的。
有的场景可能希望转换过程不可逆,即单向转换。
单向转换可以通过使用one-way来开启
类级别
<mapping type="one-way">
<class-a>org.dozer.vo.TestObjectFoo</class-a>
<class-b>org.dozer.vo.TestObjectFooPrime</class-b>
<field>
<a>oneFoo</a>
<b>oneFooPrime</b>
</field>
</mapping>
属性级别
<mapping>
<class-a>org.dozer.vo.TestObjectFoo2</class-a>
<class-b>org.dozer.vo.TestObjectFooPrime2</class-b>
<field type="one-way">
<a>oneFoo2</a>
<b>oneFooPrime2</b>
</field>
<field type="one-way">
<a>oneFoo3.prime</a>
<b>oneFooPrime3</b>
</field>
全局配置(Global Configuration)
全局配置用来设置全局的配置信息。此外,任何定制转换都是在这里定义的。
全局配置都是可选的。
<date-format>表示日期格式
<stop-on-errors>错误处理开关
<wildcard>通配符
<trim-strings>裁剪字符串开关
<configuration >
<date-format>MM/dd/yyyy HH:mm</date-format>
<stop-on-errors>true</stop-on-errors>
<wildcard>true</wildcard>
<trim-strings>false</trim-strings>
<custom-converters> <!-- these are always bi-directional -->
<converter type="org.dozer.converters.TestCustomConverter" >
<class-a>org.dozer.vo.TestCustomConverterObject</class-a>
<class-b>another.type.to.Associate</class-b>
</converter>
</custom-converters>
</configuration>
全局配置的作用是帮助你少配置一些参数,如果个别类的映射规则需要变更,你可以mapping中覆盖它。
覆盖的范例如下
<mapping date-format="MM-dd-yyyy HH:mm:ss">
<!-- 省略 -->
</mapping>
<mapping wildcard="false">
<!-- 省略 -->
</mapping>
<mapping stop-on-errors="false">
<!-- 省略 -->
</mapping>
<mapping trim-strings="true">
<!-- 省略 -->
</mapping>
定制转换(Custom Converters)
如果Dozer默认的转换规则不能满足实际需要,你可以选择定制转换。
定制转换通过配置XML来告诉Dozer如何去转换两个指定的类。当Dozer转换这两个指定类的时候,会调用你的映射规则去替换标准映射规则。
为了让Dozer识别,你必须实现org.dozer.CustomConverter接口。否则,Dozer会抛异常。
具体做法:
(1) 创建一个类实现org.dozer.CustomConverter接口。
public class TestCustomConverter implements CustomConverter {
public Object convert(Object destination, Object source,
Class destClass, Class sourceClass) {
if (source == null) {
return null;
}
CustomDoubleObject dest = null;
if (source instanceof Double) {
// check to see if the object already exists
if (destination == null) {
dest = new CustomDoubleObject();
} else {
dest = (CustomDoubleObject) destination;
}
dest.setTheDouble(((Double) source).doubleValue());
return dest;
} else if (source instanceof CustomDoubleObject) {
double sourceObj =
((CustomDoubleObject) source).getTheDouble();
return new Double(sourceObj);
} else {
throw new MappingException("Converter TestCustomConverter "
+ "used incorrectly. Arguments passed in were:"
+ destination + " and " + source);
}
}
(2) 在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">
<configuration>
<!-- 总是双向转换的 -->
<custom-converters>
<converter type="org.dozer.converters.TestCustomConverter" >
<class-a>org.dozer.vo.CustomDoubleObject</class-a>
<class-b>java.lang.Double</class-b>
</converter>
<!-- You are responsible for mapping everything between
ClassA and ClassB -->
<converter
type="org.dozer.converters.TestCustomHashMapConverter" >
<class-a>org.dozer.vo.TestCustomConverterHashMapObject</class-a>
<class-b>org.dozer.vo.TestCustomConverterHashMapPrimeObject</class-b>
</converter>
</custom-converters>
</configuration>
</mappings>
属性级
<mapping>
<class-a>org.dozer.vo.SimpleObj</class-a>
<class-b>org.dozer.vo.SimpleObjPrime2</class-b>
<field custom-converter=
"org.dozer.converters.TestCustomConverter">
<a>field1</a>
<b>field1Prime</b>
</field>
</mapping>
映射的继承(Inheritance Mapping)
Dozer支持映射规则的继承机制。
属性如果有着相同的名字则不需要在xml中配置,除非使用了hint
我们来看一个例子
<mapping>
<class-a>org.dozer.vo.SuperClass</class-a>
<class-b>org.dozer.vo.SuperClassPrime</class-b>
<field>
<a>superAttribute</a>
<b>superAttr</b>
</field>
</mapping>
<mapping>
<class-a>org.dozer.vo.SubClass</class-a>
<class-b>org.dozer.vo.SubClassPrime</class-b>
<field>
<a>attribute</a>
<b>attributePrime</b>
</field>
</mapping>
<mapping>
<class-a>org.dozer.vo.SubClass2</class-a>
<class-b>org.dozer.vo.SubClassPrime2</class-b>
<field>
<a>attribute2</a>
<b>attributePrime2</b>
</field>
</mapping>
在上面的例子中SubClass、SubClass2是SuperClass的子类;
SubClassPrime和SubClassPrime2是SuperClassPrime的子类。
superAttribute和superAttr的映射规则会被子类所继承,所以不必再重复的在子类中去声明。
发表评论
-
复习:强迫线程顺序执行方式
2019-01-03 23:42 1586方法1: 三个线程,t1,t2,t3,如果一定要按顺序执行, ... -
(转)不错的前后端处理异常的方法
2019-01-02 23:16 2021前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是 ... -
info q的极客时间大咖说等资料下载
2018-08-15 08:40 3474info q的极客时间大咖说等资料下载,还有不少思维导图 链 ... -
CXF 客户端超时时间设置(非Spring配置方式)
2018-07-03 22:38 2238import org.apache.cxf.endpoint. ... -
(转)synchronized关键字画像:正确打开方式
2018-06-14 09:25 492https://mp.weixin.qq.com/s/b3Sx ... -
CountDownLatch的例子
2018-06-13 14:10 694public class StatsDemo { ... -
两道面试题,带你解析Java类加载机制
2018-06-12 16:29 617https://mp.weixin.qq.com/s/YTa0 ... -
Spring中获取request的几种方法,及其线程安全性分析
2018-06-11 09:03 672https://mp.weixin.qq.com/s/KeFJ ... -
内部类小结
2018-06-06 10:25 439https://mp.weixin.qq.com/s/hErv ... -
JVM虚拟机小结1
2018-06-04 20:43 5451 jps -l //列出详细的类名和进程ID 2)jps ... -
windows下自带命令行工具查看CPU资源情况等
2018-06-04 12:53 3105微软提供了不少命令行 ... -
(收藏)深入分析Java的序列化与反序列化
2018-05-30 15:21 620https://mp.weixin.qq.com/s/T2Bn ... -
apache common包中的序列化工具
2018-05-30 09:10 1846什么是序列化 我们的 ... -
JAVA8 JVM的变化: 元空间(Metaspace)
2018-05-24 22:30 969本文将会分享至今为至我收集的关于永久代(Permanent G ... -
(转)服务器性能指标(一)——负载(Load)分析及问题排查
2018-05-21 21:03 1364原创: Hollis Hollis 负载 ... -
(转)对象复用
2018-05-20 15:27 866public class Student { priv ... -
mapreduce中入门中要注意的几点
2018-05-06 08:59 675在 mapreduce中,比如有如下的词: I love b ... -
HDFS的基本操作
2018-05-02 21:47 942-mkdir 在HDFS创建目录 ... -
一个不错的开源工具类,专门用来解析日志头部的,好用
2018-05-02 20:00 774一个不错的开源工具类,专门用来解析日志头部的,好用。 http ... -
介绍个不错的RESTFUL MOCK的工具wiremock
2018-04-27 21:02 1909介绍个不错的RESTFUL MOCK的工具wiremock,地 ...
相关推荐
**Dozer库详解与使用实例** Dozer是一个强大的Java Bean到Java Bean映射库,它极大地简化了对象之间的数据转换工作。与Apache的BeanUtils相比,Dozer提供了更高级别的抽象,灵活性更高,并且能够更好地处理复杂的...
在这个"dozer小例子-bean复制"中,我们将深入探讨Dozer库的使用方法以及它如何帮助我们高效地完成bean复制。 首先,Dozer的核心功能是提供对象之间的自动映射。在Java中,手动复制bean可能会导致代码冗余且易出错,...
**Dozer Eclipse插件**是面向Java开发人员的一款强大工具,尤其在进行对象-对象映射(Object-Object Mapping)时能提供巨大的便利。Dozer是一个开源库,它简化了Java对象之间的数据转换过程,而Dozer Eclipse插件则...
《Dozer复杂类型测试类详解》 在Java开发中,数据对象之间的映射是一个常见的需求,比如在服务层与表示层之间,或是不同系统间的数据交换。Dozer是一款强大的Java Bean到Java Bean映射库,它能自动进行复杂的对象...
赠送jar包:dozer-5.5.1.jar; 赠送原API文档:dozer-5.5.1-javadoc.jar; 赠送源代码:dozer-5.5.1-sources.jar; 赠送Maven依赖信息文件:dozer-5.5.1.pom; 包含翻译后的API文档:dozer-5.5.1-javadoc-API文档-...
Dozer是一个JavaBean的映射工具,用于在Java对象之间转换属性值。它类似于Apache的BeanUtils,但Dozer特别优化了复杂对象的映射,可以将一个对象的字段映射到另一个对象,这在分层架构中尤其有用。在分层架构中,...
### Dozer:强大的Java Bean映射工具 #### 一、简介与下载 Dozer是一款功能强大但使用简单的Java Bean到Java Bean映射工具,能够递归地从一个对象复制数据到另一个对象。通常,这些Java Beans会是不同复杂度的类型...
标题中的"dozer5.2 jar包"指的是Dozer库的5.2版本,这是一个Java库,主要用于对象之间的映射。它简化了Java对象到Java对象,甚至Java对象到XML文档之间的数据转换过程。Dozer不仅支持简单的属性映射,还支持复杂的...
Java EE对象拷贝工具Dozer是一款强大的数据映射库,它简化了在Java对象之间进行深度复制的过程。在软件开发中,特别是在业务层处理数据时,我们经常需要将一个对象的属性值复制到另一个对象中,Dozer提供了一个优雅...
dozer-5.5.1.jar dozer-5.5.1.jar dozer-5.5.1.jar dozer-5.5.1.jar
《Dozer:强大的JavaBean映射工具》 在Java开发中,对象间的属性映射是一项常见的任务,尤其是在数据转换和接口交互中。Apache的BeanUtils是这类问题的一个基础解决方案,但当面临更复杂的映射需求时,其功能就显得...
"dozer5.5.1 ( 可集成spring 及 OSGi )" 指的是Dozer库的一个特定版本,即5.5.1,它具有与Spring框架和OSGi容器集成的能力。这意味着开发人员可以将Dozer作为数据映射工具,在这些环境中无缝地使用。 **描述解析:*...
**Dozer详解** Dozer是一款强大的Java到Java对象映射库,它可以帮助开发者在不同的对象模型之间进行数据转换。在处理复杂的数据结构时,Dozer提供了便捷的方式,减少了手动转换代码的工作量,使得代码更加简洁、可...
《Dozer 5.3.2:Java数据映射与校验利器》 在Java开发领域,数据转换和校验是常见的任务,尤其在处理不同系统间的数据交换时。Dozer是一个强大的开源库,专为解决此类问题而设计。本文将深入探讨Dozer 5.3.2版本的...
**Dozer 使用详解** Dozer 是一个开源的 Java 对象到对象映射库,它能够帮助开发者在 Java 应用程序中将一个对象模型映射到另一个对象模型。这个工具在处理复杂的数据转换时非常有用,尤其是在数据绑定、数据复制...
赠送jar包:dozer-5.5.1.jar; 赠送原API文档:dozer-5.5.1-javadoc.jar; 赠送源代码:dozer-5.5.1-sources.jar; 赠送Maven依赖信息文件:dozer-5.5.1.pom; 包含翻译后的API文档:dozer-5.5.1-javadoc-API文档-...
Dozer 是一个强大的 Java 对象映射框架,它简化了对象到对象之间的转换工作,尤其在处理复杂的数据结构时。这个工具广泛应用于企业级应用,因为它可以极大地减少手动编写转换代码的工作量。在这个总结中,我们将深入...
dozer是一款优秀的java bean映射开源框架,完成深度转换Bean<->Bean的Mapper实现
dozer是一种JavaBean的映射工具,类似于Apache的BeanUtils。它可以灵活地处理复杂类型之间的映射。不但可以进行简单的属性映射、复杂的类型映射、双向映射、递归映射等,并且可以通过XML配置文件进行灵活的配置。 ...