什么是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. Python数据类型-03.序列-列表和元组

    本文主要记录关于Python序列中列表和元组的定义特点和常用方法 1.序列(sequence) 1.1.序列的定义 序列是一组有顺序的元素的集合(其实是是对象的集合,后期会引入“对象”这个概念)序列包 ...

  2. 响应: 500 OOPS: priv_sock_get_int 错误: 读取目录列表失败

    /************************************************************************* * 响应: 500 OOPS: priv_sock ...

  3. python 用 __all__ 暴露接口

    非常典型的python的用法 refer to : http://python-china.org/t/725

  4. django-redis 中文文档

    Andrey Antukh, niwi@niwi.be 4.7.0 翻译: RaPoSpectre 1. 介绍 django-redis 基于 BSD 许可, 是一个使 Django 支持 Redis ...

  5. prisma 集成tidb 安装试用

    以前官方提供的ansible 的脚本,现在有了docker的版本,可以方便测试使用 实际完整配置参考 https://github.com/rongfengliang/prisma-tidb 安装ti ...

  6. Spring Boot 报错:Error creating bean with name 'entityManagerFactory' defined in class path resource

    spring boot 写一个web项目,在使用spring-data-jpa的时候,启动报如下错误: Error starting ApplicationContext. To display th ...

  7. HttpHelp 请求帮助类

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

  8. ETL流程概述及常用实现方法

    ETL流程概述及常用实现方法 http://blog.csdn.net/btkuangxp/article/details/48224187 目录(?)[-] 1抽取作业 1手工开发抽取作业时候的常用 ...

  9. pycharm修改代码模板支持中文输出

    python2.x默认不支持中文输出,需要在py的开头添加 #coding: utf- 在pycharm里面,选项,editor,file and code templates,选择python sc ...

  10. C语言课程设计——电影院订票系统

    1. 课题简介 大家都爱看电影,现请参考一个熟悉电影票预订系统,实现C语言版的订票系统.了解订票如何实现的.系统主要有2类用户:管理员用户和顾客用户. 管理员用户登录系统后,实现电影放映厅信息管理和电 ...