java dozer数组_Dozer 使用小结

本文详细介绍了JavaBean映射工具Dozer的使用,包括安装、配置、与Spring的整合、数据类型转换、映射配置等,并通过实例展示了如何进行对象映射,包括注解、API和XML方式。
摘要由CSDN通过智能技术生成

这篇文章是本人在阅读Dozer官方文档(5.5.1版本,官网已经一年多没更新了)的过程中,整理下来我认为比较基础的应用场景。

本文中提到的例子应该能覆盖JavaBean映射的大部分场景,希望对你有所帮助。

概述

Dozer是什么?

Dozer是一个JavaBean映射工具库。

它支持简单的属性映射,复杂类型映射,双向映射,隐式显式的映射,以及递归映射。

它支持三种映射方式:注解、API、XML。

安装

引入jar包

maven方式

如果你的项目使用maven,添加以下依赖到你的pom.xml即可:

net.sf.dozer

dozer

5.4.0

非maven方式

如果你的项目不使用maven,那就只能发扬不怕苦不怕累的精神了。

使用Dozer需要引入Dozer的jar包以及其依赖的第三方jar包。

Eclipse插件

Dozer有插件可以在Eclipse中使用(不知道是否好用,反正我没用过)

插件地址: http://dozer.sourceforge.net/eclipse-plugin

使用

将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文件。

标签中允许你定义和,对应着相互映射的类。

标签里定义要映射的特殊属性。需要注意和对应,和对应,聪明的你,猜也猜出来了吧。

xsi:schemaLocation="http://dozer.sourceforge.net

http://dozer.sourceforge.net/schema/beanmapping.xsd">

org.zp.notes.spring.common.dozer.vo.NotSameAttributeA

org.zp.notes.spring.common.dozer.vo.NotSameAttributeB

name

value

与Spring整合

配置 DozerBeanMapperFactoryBean

在src/test/resources目录下添加spring/spring-dozer.xml文件。

Dozer与Spring的整合很便利,你只需要声明一个DozerBeanMapperFactoryBean,

将所有的dozer映射配置文件作为属性注入到mappingFiles,

DozerBeanMapperFactoryBean会加载这些规则。

spring-dozer.xml文件范例

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">

classpath*:dozer/dozer-mapping.xml

自动装配

至此,万事具备,你只需要自动装配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文件中。

one

onePrime

字符串和日期映射(String to Date Mapping)

字符串在和日期进行映射时,允许用户指定日期的格式。

格式的设置分为三个作用域级别:

属性级别

对当前属性有效(这个属性必须是日期字符串)

dateString

dateObject

类级别

对这个类中的所有日期相关的属性有效

org.dozer.vo.TestObject

org.dozer.vo.TestObjectPrime

dateString

dateObject

全局级别

对整个文件中的所有日期相关的属性有效。

MM/dd/yyyy HH:mm

org.dozer.vo.TestObject

org.dozer.vo.TestObjectPrime

dateString

dateObject

集合和数组映射(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的范例:

hintList

hintList

org.dozer.vo.TheFirstSubClassPrime

累计映射和非累计映射(Cumulative vs. Non-Cumulative List Mapping)

如果你要转换的目标类已经初始化,你可以选择让Dozer添加或更新对象到你的集合中。

而这取决于relationship-type配置,默认是累计。

它的设置有作用域级别:

全局级

non-cumulative

类级别

属性级别

hintList

hintList

org.dozer.vo.TheFirstSubClass

org.dozer.vo.TheFirstSubClassPrime

移动孤儿(Removing Orphans)

这里的孤儿是指目标集合中存在,但是源集合中不存在的元素。

你可以使用remove-orphans开关来选择是否移除这样的元素。

srcList

destList

深度映射(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;

}

映射规则

org.zp.notes.spring.common.dozer.vo.Source

org.zp.notes.spring.common.dozer.vo.Dest

info

info.content

排除属性(Excluding Fields)

就像任何团体都有捣乱分子,类之间转换时也有想要排除的因子。

如何在做类型转换时,自动排除一些属性,Dozer提供了几种方法,这里只介绍一种比较通用的方法。

更多详情参考官网。

field-exclude可以排除不需要映射的属性。

fieldToExclude

fieldToExclude

单向映射(One-Way Mapping)

注:本文的映射方式,无特殊说明,都是双向映射的。

有的场景可能希望转换过程不可逆,即单向转换。

单向转换可以通过使用one-way来开启

类级别

org.dozer.vo.TestObjectFoo

org.dozer.vo.TestObjectFooPrime

oneFoo

oneFooPrime

属性级别

org.dozer.vo.TestObjectFoo2

org.dozer.vo.TestObjectFooPrime2

oneFoo2

oneFooPrime2

oneFoo3.prime

oneFooPrime3

全局配置(Global Configuration)

全局配置用来设置全局的配置信息。此外,任何定制转换都是在这里定义的。

全局配置都是可选的。

表示日期格式

错误处理开关

通配符

裁剪字符串开关

MM/dd/yyyy HH:mm

true

true

false

org.dozer.vo.TestCustomConverterObject

another.type.to.Associate

全局配置的作用是帮助你少配置一些参数,如果个别类的映射规则需要变更,你可以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中引用定制的映射规则

引用定制的映射规则也是分级的,你可以酌情使用。

全局级

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://dozer.sourceforge.net

http://dozer.sourceforge.net/schema/beanmapping.xsd">

org.dozer.vo.CustomDoubleObject

java.lang.Double

type="org.dozer.converters.TestCustomHashMapConverter" >

org.dozer.vo.TestCustomConverterHashMapObject

org.dozer.vo.TestCustomConverterHashMapPrimeObject

属性级

org.dozer.vo.SimpleObj

org.dozer.vo.SimpleObjPrime2

"org.dozer.converters.TestCustomConverter">

field1

field1Prime

映射的继承(Inheritance Mapping)

Dozer支持映射规则的继承机制。

属性如果有着相同的名字则不需要在xml中配置,除非使用了hint

我们来看一个例子

org.dozer.vo.SuperClass

org.dozer.vo.SuperClassPrime

superAttribute

superAttr

org.dozer.vo.SubClass

org.dozer.vo.SubClassPrime

attribute

attributePrime

org.dozer.vo.SubClass2

org.dozer.vo.SubClassPrime2

attribute2

attributePrime2

在上面的例子中SubClass、SubClass2是SuperClass的子类;

SubClassPrime和SubClassPrime2是SuperClassPrime的子类。

superAttribute和superAttr的映射规则会被子类所继承,所以不必再重复的在子类中去声明。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值