以前通常使用的都是Jakarta Commons BeanUtils 包来做bean之间的属性拷贝,这次在看springside3.1的时候发现了里面推荐Dozer来做,而不是BeanUtils包很是纳闷。于是上Dozer官网进行了一番查看,作了一些学习笔记的摘要。
其实看老外写的英文文档还是很舒服的,没有晦涩的语句和单词,反而觉得那些高手写出来的寥寥几句话蕴含了一种技术高度的积累,可以体会到另一层面的思路。言归正传
一。Why Map?
为什么要做Mapping的映射?特别是在使用Webservice和Hessian等垮系统模块的时候,Model对象通常使用DTO解耦,eg。(springsied的例子)
Web Service传输Role信息的DTO.
package org.springside.examples.miniservice.ws.user.dto;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springside.examples.miniservice.ws.Constants;
/**
* Web Service传输Role信息的DTO.
*
* 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.
*
* @author calvin
*/
@XmlType(name = "Role", namespace = Constants.NS)
public class RoleDTO {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 重新实现toString()函数方便在日志中打印DTO信息.
*/
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
在自己的系统内部,定义User类,
package org.springside.examples.miniservice.entity.user;
public class User extends IdEntity {
}
使用Dozer来进行转换,将外部Webservice参数对象map到系统内部的user对象
List<User> userList = userManager.getAll();
List<UserDTO> userDTOList = new ArrayList<UserDTO>();
for (User userEntity : userList) {
userDTOList.add((UserDTO) dozer.map(userEntity, UserDTO.class));
}
Dozer主页上的解释:
For distributed systems, a side effect is the passing of
domain objects between different systems. Typically, you won't want
internal domain objects exposed externally and won't allow for external
domain objects to bleed into your system.
Data object mapping
is an important part of layered service oriented architectures. Pick
and choose the layers you use mapping carefully. Do not go overboard as
there is maintenance and performance costs associated with mapping data
objects between layers.
Mapping between data objects has been
traditionally addressed by hand coding value object assemblers (or
converters) that copy data between the objects. Most programmers will
develop some sort of custom mapping framework and spend countless hours
and thousands of lines of code mapping to and from their different data
object.
二。
chooice :Jakarta Commons Bean Utils package ,Dozer
Dozer supports simple property mapping, complex type mapping, bi-directional mapping, implicit-explicit mapping, as well as recursive mapping. This includes mapping collection attributes that also need mapping at the element level.
可以明显的看到,Dozer支持复杂映射,自定义配置映射。相比起Beanutil的方法,显然可以做到更多的事情。(即便是默认的转换,Dozer也能够自动完成一样变量名字段之间的类型转换)
三。试用一把
step1
Mapper mapper = DozerBeanMapperSingletonWrapper.getInstance();
DestinationObject destObject = mapper.map(sourceObject, DestinationObject.class);
step2
:Specifying Custom Mappings via XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mappings PUBLIC "-//DOZER//DTD MAPPINGS//EN"
"http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mappings>
<configuration>
<stop-on-errors>true</stop-on-errors>
<date-format>MM/dd/yyyy HH:mm</date-format>
<wildcard>true</wildcard>
</configuration>
<mapping>
<class-a>yourpackage.yourSourceClassName</class-a>
<class-b>yourpackage.yourDestinationClassName</class-b>
<field>
<A>yourSourceFieldName</A>
<B>yourDestinationFieldName</B>
</field>
</mapping>
other custom class mappings would go here.......
</mappings>
3.注入配置Injecting Custom Mapping Files
Dozer同样支持IOC容器的注入(现在很难找到不支持spring容器的项目了),同样也支持代码方式的注入:
The Dozer mapping xml file(s) define any custom mappings that can't be automatically performed by the Dozer mapping engine. Any custom Dozer mapping files need to be injected into the Mapper implementation(org.dozer.DozerBeanMapper). Both setter-based and constructor-based injection are supported.
Preferably, you will be using an IOC framework such as Spring for these Dozer injection requirements. Alternatively, the injection of mapping files can be done programatically. Below is a programmatic approach to creating a bean mapper. Note that this is NOT the recommended way to retrieve the bean mapper . Each new instance needs to be initialized and this consumes time as well as resources. If you are using the mapper this way just wrap it using the singleton pattern.
先看spring方式的注入:
<bean id="mapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>dozer-global-configuration.xml</value>
<value>dozer-bean-mappings.xml</value>
<value>more-dozer-bean-mappings.xml</value>
</list>
</property>
</bean>
再看代码方式的注入(!!!非推荐方式)
Each new instance needs to be initialized and this consumes time as well as resources. If you are using the mapper this way just wrap it using the singleton pattern.
List myMappingFiles = new ArrayList();
myMappingFiles.add("dozerBeanMapping.xml");
myMappingFiles.add("someOtherDozerBeanMappings.xml");
DozerBeanMapper mapper = new DozerBeanMapper();
mapper.setMappingFiles(myMappingFiles);
DestinationObject destObject = mapper.map(sourceObject, DestinationObject.class);
springside里面实现的Dozer单例:
package org.springside.modules.utils;
import net.sf.dozer.util.mapping.DozerBeanMapper;
import net.sf.dozer.util.mapping.MapperIF;
/**
* 辅助DTO复制的Dozer工具类的单例wrapper.
*
* Dozer在同一JVM里使用单例即可,无需重复创建.
* 但Dozer4自带的DozerBeanMapperSingletonWrapper必须使用dozerBeanMapping.xml作参数初始化,因此重新实现无配置文件的版本.
*
* @author calvin
*/
public final class DozerMapperSingleton {
private static MapperIF instance = new DozerBeanMapper();//使用预初始化避免并发问题.
private DozerMapperSingleton() {
}
public static MapperIF getInstance() {
return instance;
}
}
分享到:
相关推荐
推土机(Dozer)是Java领域中一个强大的对象到对象映射库,它使得在不同对象模型之间复制数据变得更加简单。这个库被设计用来减轻Java开发者的负担,避免手动编写大量的复制代码,特别是在处理复杂的数据结构时。...
(可选)通过选择单击任何推土机图标,“删除”图标及其左侧的所有内容都将被隐藏/显示 :laptop_computer: 用法 移动要隐藏的图标,直到单击第二个推土机图标的左侧 移动要隐藏的图标,直到在第三个推土机图标的...
本文将深入探讨“sandbox_dozer”项目,它涉及到使用推土机(Dozer)这个bean映射库。Dozer库是为了帮助开发者在不同对象之间进行数据映射,从而减少代码量,提高开发效率。 首先,让我们了解什么是bean映射。在...
推土机价格预测模型——Bull-Dozer-ML-Model 是一个利用机器学习技术来预测推土机市场价格的项目。这个模型旨在帮助行业参与者,如制造商、经销商和投资者,根据历史数据对推土机的未来售价进行准确的估算,从而优化...
描述中提到"推土机"可能是项目的一个别名或者代号,暗示了它有强大的数据处理能力,就像推土机在工程中能够处理大量泥土一样。项目基于版本 0.11.1,这表明它是一个持续更新和发展的软件,用户可以根据这个版本号来...
推土机 MongoDB的Rest API接口 一个简单的命令行应用程序,用于在MongoDB数据库之上添加REST API。 通过可通过cli轻松创建的JSON Web令牌(JWT)来控制对API的访问。 令牌可以包含授予的范围,这些范围限制了对特定...
隐藏状态栏图标,使Mac外观更整洁。 使用Homebrew Cask进行安装:brew ...将要隐藏的图标移到两个推土机图标的左侧。 左键单击推土机图标之一以隐藏/显示状态栏图标。 右键单击推土机图标之一以打开设置。 签出此GIF到
Dozer Annotations 通过 Java 5 注释为 Dozer 提供了一个简单的内嵌接口。 这提供了比 XML 配置文件更大的灵活性,包括类型安全、跨应用程序适用性和代码内配置。 需要推土机
推土机实验使用推土机自定义转换器以及基于Spring Bean的声明的一些实验。描述该项目构成了一组用于以下用例的基于推土机的特殊用途定制转换器。 源类和目标类是可映射的实体, 将调用该可映射的实体来完成映射。 ...
推土机 用于MongoDB的Dozer Rest API接口的客户端 注意:将会有更多文档。 安装 $ npm install dozer-client 用法 去做 执照 ISC:copyright:亚当·丹尼尔(Adam Daniel)
推土机 积极的贡献者 我们一直在寻求更多帮助。 以下是当前的活动列表: 核 @garethahealy @ orange-buffalo ?? 原虫 @jbq @garethahealy ?? Spring4 / Springboot @vadeg @garethahealy ?? 为什么要地图? ...
推土机演示 Dozer的demo,它是一个开源的不同java层的映射工具。 Dozer 是一个从 Java Beans 到 Java Beans 的开源 Java 映射器。 当您在不同层之间传输对象时,它非常有用,例如,从Hibernate数据对象、业务对象到...
最初的用途是从一组Hibernate DAO对象中取出数据,并从中创建各种XML DOM对象。... 乍一看,这似乎与推土机(http://dozer.sourceforge.net)相似,但主要区别在于这是代码生成,并且没有在运行时使用自省的开销。
- **推土机(Dozer)**: 一种重型工程机械,主要用于平整土地或移动大量物料。 - **平衡轴(Equalizing Shaft)**: 用于均衡多点受力的轴类部件。 #### 七、其他术语 - **皮带跑偏装置(Belt Slip Tracking)**: ...
36. **推土机(dozer)**:用于推平地面或堆积物料的重型工程机械。 37. **平衡轴(EQUALIZING SHAFT)**:用于平衡机械系统中各部分负载的轴。 38. **链式牵引(Chain drag)**:使用链条拉动物体的传动方式。 ...