对象转换利器之Dozer
什么是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的更多相关文章
- Dozer数据对象转换神器
Dozer数据对象转换神器
- C#编程利器之二:结构与枚举(Structure and enumeration)【转】
C#编程利器之二:结构与枚举(Structure and enumeration) 在上一篇文章中,介绍了类如何封装程序中的对象.而实际中,出了类可以封装对象外,结构和枚举也可以封装一些对象,本文将着 ...
- php调试利器之phpdbg
信海龙的博客 php调试利器之phpdbg 简介 PHPDBG是一个PHP的SAPI模块,可以在不用修改代码和不影响性能的情况下控制PHP的运行环境. PHPDBG的目标是成为一个轻量级.强大.易用的 ...
- 后台任务利器之Hangfire
后台任务利器之Hangfire 一.简述 Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在.net core的环境中,由Core自带的DI管理着生命周期,免去了在NF4 ...
- .NET Core开源组件:后台任务利器之Hangfire 转载 https://www.cnblogs.com/chenug/p/6655636.html
.NET Core开源组件:后台任务利器之Hangfire 一.简述 Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在.net core的环境中,由Core自带的D ...
- 破解浏览器同源政策利器之JSONP
本文是在了解了浏览器的同源规则之后,学习了破解这个规则的一个简单有效的方法->JSONP.主要通过阮一峰老师的博客学习 浏览器的同源规则 有这样一个背景,如果你通过银行的网站进行的取钱的交易,而 ...
- Win下必备利器之Cmder
诚言,对于开发码字者,Mac和Linux果断要比Windows更贴心;但只要折腾下,Windows下也是有不少利器的.之前就有在Windows下效率必备软件一文中对此做了下记载:其虽没oh-my-zs ...
- 采用Lambda表达式快速实现实体模型对象转换到DTO
在项目中,采用code first时建立的模型对象不能直接用于数据传输,需要从新根据需求建立Dto对象 为什么需要建立Dto对象呢? DTO即数据传输对象.之前不明白有些框架中为什么要专门定义DTO来 ...
- [转]Json转换神器之Google Gson的使用
这几天,因为项目的需要,接触了Google的Gson库,发现这个东西很好用,遂记下简单的笔记,供以后参考.至于Gson是干什么的,有什么优点,请各位同学自行百度.话不多说,切入正题: 1. 下载Gso ...
随机推荐
- VirtualBox的vdi映像导入遇到的uuid冲突问题 (转)
virtualbox导入vdi文件时出现下面的问题: 打开hard disk D:\software\GT5.0.0.vdi 失败 Cannot register the hard disk 'D ...
- Phonegap项目创建 编译 安装 运行
一.创建 Phonegap项目 1. cd workspace 2.创建phonegap项目 cordova create 目录 识别符 显示名 例如:cordova create hello com ...
- python的面向对象
1.self 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值.这个特别的变量指对象本身,按照惯例它的 ...
- ExtJs 扩展类CheckColumn的使用(事件触发)
[javascript] view plain copy print? 使用 Extjs 在进行数据库编程经常会遇到 checkbox 的问题(奇怪网上却没有此类文章不知道其他人是怎么解决的,在此贴上 ...
- ruby里面module和class的区别
一句话概括,就是 class可以实例化 module不可以 别的都一样 关于继承的一点区别 class是使用<作为继承的关键字,只支持单继承 module是使用include来做实例继承(实例化 ...
- redis 操作大全 PHP-redis中文文档
转自 : http://www.cnblogs.com/weafer/archive/2011/09/21/2184059.html phpredis是php的一个扩展,效率是相当高有链表排序功能, ...
- 解决php收邮件乱码问题
function test($strHead){ if(ereg("=\?.{0,}\?[Bb]\?",$strHead)){ $arrHead=split("=\?.{ ...
- java基础-Map的静态初始化以及Map的遍历等.....................
1.map的静态初始化,以及map遍历的几种方法: package com.cy.test; import java.util.HashMap; import java.util.Iterator; ...
- Clearsigned file isn't valid, got 'NOSPLIT' (does the network require authentication?)
ubuntu16在运行sudo apt-get update 命令后,报出错误: Clearsigned file isn't valid, got 'NOSPLIT' (does the netwo ...
- 认识Linux操作系统
Linux系统是一个类似UNIX的操作系统 认识Linux的来世与今生 1.Linux系统的历史 Linux系统是一个类似UNIX的操作系统,Linux系统是UNIX在微机上的完整实现,它的标志是一个 ...