什么是Dozer

Dozer是一个Java对象转换工具,可以在JavaBean和JavaBean之间进行递归数据复制,并且适应不同复杂的类型。Dozer会直接将名称相同的属性进行复制,属性名不同或者有特殊的要求则可以在xml中进行配置。

除了使用Dozer,当然你还由其他选择:

典型的解决方案就是手动拷贝,弊端很明显,代码中充斥大量Set 和Get方法,真正的业务被埋藏值与值的拷贝之中。

另一种方案就是使用BeanUtil,但BeanUtil不够很好的灵活性,有时候还不得不手动拷贝。Dozer可以灵活的对对象进行转换,且使用简单。

Dozer做对象转换有什么特点

  • 默认属性Mapping,即如果属性名称一样, 就不需要显示配置,Dozer会自动处理。
  • 自动做类型转换,即如果两个属性名称一样,即使类型不一样,在Dozer可理解范围内,帮你处理得妥妥的。Dozer可理解的类型范围非常广,这会极大的提升程序员的生产力
  • 不必担心中间的null property,遇到null property,Dozer会把对应的所有属性全部设置为null,而不会抛NullPointerExeception。

Dozer可以自动做数据类型转换。当前,Dozer支持以下数据类型转换(都是双向的)(注:Primitive 基本数据类型 , 后面带 Wrapper 是包装类,Complex Type 是复杂类型。):

•   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 到复杂类型 , 如果复杂类型包含一个 String 类型的构造器
• 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的对象转换。

在普通Java项目中使用Dozer

在pom.xml中增加依赖

<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency> 

使用Dozer进行类转换

public class Main {

    public static void main(String[] args) {
DozerBeanMapper mapper = new DozerBeanMapper();
UserDO userDO = new UserDO();
userDO.setName("hollis");
userDO.setAddress("hz");
userDO.setAge(25);
userDO.setCompanyId(1);
userDO.setBirthday(new Date());
userDO.setGender("male");
userDO.setEducation("1");
userDO.setNickName("hollis");
userDO.setPoliticalStatus("3");
UserVO userVO = (UserVO) mapper.map(userDO, UserVO.class);
System.out.println(userVO);
}

特殊的字段转换
在使用mapper进行转换前,设置一个或多个mapping文件

List myMappingFiles = new ArrayList();
myMappingFiles.add("dozer-mapping.xml");
mapper.setMappingFiles(myMappingFiles); 

配置dozer-mapping.xml文件

数据类型不一致,或者名称不相同或者有级联关系等情况下,可以通过文件dozer-mapping.xml来进行定制Bean的转换

<?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>
<class-a>com.hollis.lab.UserDO</class-a>
<class-b>com.hollis.lab.UserVO</class-b>
</mapping>
</mappings> 

在JavaWeb项目中使用Dozer

在pom.xml中增加依赖

<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency> 

使用Spring集成dozer

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="baseMapper" class="org.dozer.spring.DozerBeanMapperFactoryBean">
<property name="mappingFiles">
<list>
<value>classpath:mapping/dozer-mapping.xml</value>
</list>
</property>
</bean>
</beans> 

使用baseMapper进行Bean的转换

@Autowired
private Mapper baseMapper;
private UserVO doToVo(UserDO userDO){
if(userDO == null) return null;
UserVO vo = baseMapper.map(userDO, UserVO.getClass());
if(userDO.getCompanyId != null) getCompany(vo);
return vo;

通过以上的代码加配置,我们就实现了从DO转换到VO的部分操作,之所以说是部分操作,是因为我们在dozer-mapping.xml并没有做多余的配置,只是使用dozer将DO中和VO中共有的属性转换了过来。对于其他的类型不同或者名称不同等的转换可以参考官网例子通过设置dozer-mapping.xml文件来实现。

上面还有一个getCompany()没有实现。这个方法其实就是通过companyId查询出company实体然后在赋值给UserVO中的company属性。

注意事项

1:

DestinationObject destObject =  mapper.map(sourceObject, DestinationObject.class);

DestinationObject必须有无参构造方法,不然会报java.lang.NoSuchMethodException: com.net.vo.CompanyVo.<init>()错误。

2:

SourceObject和DestinationObject中属性必须可读写,比如提供公开的get或set方法,不然无法复制数据。其实,转化的过程是通过调用UserDO中的getter方法和UserVO中的setter方法来实现的。

3:

dozer正常输出日志需要增加两个jar包

slf4j-api和slf4j-simple,或者,slf4j-api和slf4j-log4j12

例如:

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency> 

参考资料

使用Dozer优雅的将DO转换成VO:http://www.hollischuang.com/archives/1613

Dozer使用简记:http://tedhacker.top/2016/08/17/Dozer%E4%BD%BF%E7%94%A8%E7%AE%80%E8%AE%B0/

Dozer 使用小结:https://www.jianshu.com/p/bf8f0e8aee23

对象转换利器之Dozer的更多相关文章

  1. Dozer数据对象转换神器

    Dozer数据对象转换神器  

  2. C#编程利器之二:结构与枚举(Structure and enumeration)【转】

    C#编程利器之二:结构与枚举(Structure and enumeration) 在上一篇文章中,介绍了类如何封装程序中的对象.而实际中,出了类可以封装对象外,结构和枚举也可以封装一些对象,本文将着 ...

  3. php调试利器之phpdbg

    信海龙的博客 php调试利器之phpdbg 简介 PHPDBG是一个PHP的SAPI模块,可以在不用修改代码和不影响性能的情况下控制PHP的运行环境. PHPDBG的目标是成为一个轻量级.强大.易用的 ...

  4. 后台任务利器之Hangfire

    后台任务利器之Hangfire 一.简述 Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在.net core的环境中,由Core自带的DI管理着生命周期,免去了在NF4 ...

  5. .NET Core开源组件:后台任务利器之Hangfire 转载 https://www.cnblogs.com/chenug/p/6655636.html

    .NET Core开源组件:后台任务利器之Hangfire   一.简述 Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在.net core的环境中,由Core自带的D ...

  6. 破解浏览器同源政策利器之JSONP

    本文是在了解了浏览器的同源规则之后,学习了破解这个规则的一个简单有效的方法->JSONP.主要通过阮一峰老师的博客学习 浏览器的同源规则 有这样一个背景,如果你通过银行的网站进行的取钱的交易,而 ...

  7. Win下必备利器之Cmder

    诚言,对于开发码字者,Mac和Linux果断要比Windows更贴心;但只要折腾下,Windows下也是有不少利器的.之前就有在Windows下效率必备软件一文中对此做了下记载:其虽没oh-my-zs ...

  8. 采用Lambda表达式快速实现实体模型对象转换到DTO

    在项目中,采用code first时建立的模型对象不能直接用于数据传输,需要从新根据需求建立Dto对象 为什么需要建立Dto对象呢? DTO即数据传输对象.之前不明白有些框架中为什么要专门定义DTO来 ...

  9. [转]Json转换神器之Google Gson的使用

    这几天,因为项目的需要,接触了Google的Gson库,发现这个东西很好用,遂记下简单的笔记,供以后参考.至于Gson是干什么的,有什么优点,请各位同学自行百度.话不多说,切入正题: 1. 下载Gso ...

随机推荐

  1. Swift 获取plist文件展示在TableView上

    // 1.定义二维数组 var data:[[String]]! override func viewDidLoad() { super.viewDidLoad() // 2.实例化tableView ...

  2. Session History 属性和方法

    History 接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录. js通过window.history来访问和操作的,操作的范围是某个tab的会话历史记录. 这个tab打开后,tab内的 ...

  3. Windows与.NET Framework、数据库版本对应关系

    ================== windows XP/server 2003 (.NET Framework与 SQL Server\Oracle) 支持.NET版本:.NET Framewor ...

  4. html5 data属性的使用

    html5 data属性定义和用法 <ul> <li data-animal-type="bird">Owl</li> <li data- ...

  5. ELF文件和BIN文件

    文件的内容:1. BIN文件是 raw binary 文件,这种文件只包含机器码.2. ELF文件除了机器码外,还包含其它额外的信息,如段的加载地址,运行地址,重定位表,符号表等. 所以ELF文件的体 ...

  6. Accessing data in Hadoop using dplyr and SQL

    If your primary objective is to query your data in Hadoop to browse, manipulate, and extract it into ...

  7. 黄聪:利用iframe实现ajax 跨域通信的解决方案(转)

    原文:http://www.cnblogs.com/xueming/archive/2013/02/01/crossdomainajax.html 在漫长的前端开发旅途上,无可避免的会接触到ajax, ...

  8. 关于layoutparam 请铭记。。。。

    //rl_pager 是RelativeLayout findViewById(R.id.rl_pager).setLayoutParams(new RelativeLayout.LayoutPara ...

  9. 基于PhantomJS的网页抓取及写入文件

    # coding=utf-8 from selenium import webdriver from selenium.webdriver.common.desired_capabilities im ...

  10. PY安装模块

    Python安装失败原因 0环境 , pip版本一般为 7.x , 所以一般需要先升级pip版本 , 也就是执行 ```shellpython -m pip install --upgrade pip ...