SpringBoot学习小结之Dozer
前言
Dozer是一个Java Bean到Java Bean的Mapper,可将数据从一个对象递归复制到另一个对象。Dozer支持简单属性、复杂属性映射,Java中常见集合相互映射和递归映射。
Dozer可以看做是一个对象属性拷贝工具,适用于模型转换,同样的工具还有很多,例如Cglib的BeanCopier、Apache 的PropertyUtils、Spring的BeanUtils。
Dozer与上述工具相比,最大的优势就是支持不同名属性映射。当然,最大的劣势就是性能差。这里附上一张其他博主做性能测试的表格。相关博文
类 | 方法 | 归属 | 单次耗时[ms] | 100万次耗时[ms] | 平均耗时[ms] |
---|---|---|---|---|---|
BeanCopier | copy | Cglib | 0.005071 | 58.415201 | 0.000058 |
BeanUtils | copyProperties | Spring | 0.072082 | 2155.744378 | 0.002155 |
PropertyUtils | copyProperties | Apache | 0.164118 | 16714.877932 | 0.016714 |
DozerBeanMapper | map | Dozer | 0.598338 | 19158.842820 | 0.019158 |
所以,当系统数据量不大、对性能要求不高,或者需要非同名属性映射时可以考虑使用Dozer。
springboot使用dozer pom依赖。
<dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-spring-boot-starter</artifactId><version>6.5.0</version>
</dependency>
一、Configuration配置
简单配置
application.yml
dozer:mapping-files: classpath:dozer/first.xml
dozer.mapping-files
是dozer-spring-boot-start
自带属性,可以通过application.yml
配置,多个用逗号隔开通配符配置
默认不支持通配符配置,需要编写配置文件
dozer:mapping-files: classpath:dozer/*.xml
@Configuration public class DozerConfig {@Beanpublic DozerBeanMapperFactoryBean dozerMapper(@Value("${dozer.mapping-files}") Resource[] resources) throws IOException {DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();dozerBeanMapperFactoryBean.setMappingFiles(resources);return dozerBeanMapperFactoryBean;} }
mapping配置文件示例
<?xml version="1.0" encoding="UTF-8"?> <mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd"><mapping><class-a>org.dozer.vo.TestObject</class-a><class-b>org.dozer.vo.TestObjectPrime</class-b><field><a>one</a><b>onePrime</b></field></mapping> </mappings>
二、工具类
@Component
public class DozerUtil {private static Mapper dozerMapper;@Autowiredpublic void setDozerMapper(Mapper dozerMapper) {DozerUtil.dozerMapper = dozerMapper;}/*** 构造新的destinationClass实例对象,通过source对象中的字段内容* 映射到destinationClass实例对象中,并返回新的destinationClass实例对象。** @param source 源数据对象* @param destinationClass 要构造新的实例对象Class*/public static <T> T map(Object source, Class<T> destinationClass) {return dozerMapper.map(source, destinationClass);}/*** 将对象source的所有属性值拷贝到对象destination中.** @param source 对象source* @param destinationObject 对象destination*/public static void map(Object source, Object destinationObject) {dozerMapper.map(source, destinationObject);}/*** List数据源映射** @param sourceList* @param destinationClass* @param <T>* @return List<T>*/public static <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {List destinationList = new ArrayList<>();for (Iterator iterator = sourceList.iterator(); iterator.hasNext(); ) {Object sourceObject = iterator.next();Object destinationObject = dozerMapper.map(sourceObject, destinationClass);destinationList.add(destinationObject);}return destinationList;}
三、常用的几种映射
Bean到Bean
Bean和Bean之间映射,这是最常见的映射。Dozer默认同名映射,即不用配置文件就可以实现Bean之间的同名映射。使用Mapping配置文件即可实现非同名属性的映射。
Bean List到Bean List
实际上还是Bean之间的映射,将srcList中Bean映射完后装入destList中
Date到String
单个字段
<field><a date-format="yyyy-MM-dd HH:mm:ss">dateObject</a><b>dateString</b> </field>
单个类所有Date字段
<mapping date-format="yyyy-MM-dd HH:mm:ss"> </mapping>
HashMap到Bean
hashMap可以通过将key配置成Bean的field名,和Bean映射
四、高级功能
自定义转换器
自定义类型转换器需要实现
com.github.dozermapper.core.CustomConverter
接口或者继承com.github.dozermapper.core.DozerConverter
类以CustomConverter示例:Enum映射String
public enum Color {RED("red"), GREEN("green"), YELLOW("yellow");private String value;Color(String value) {this.value = value;}public static Color newInstance(String color) throws Exception {switch (color) {case "red" : return RED;case "green": return GREEN;case "yellow": return YELLOW;default: throw new Exception("unknow color:" + color);}}@Overridepublic String toString() {return value;} }
@Data public class FlowerVo {private Integer id;private String purchaseDateStr;private String colorStr; }
@Data public class Flower {private Integer id;private Date purchaseDate;private Color color; }
public class EnumColorCustomConverter implements CustomConverter {@Overridepublic Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {if (sourceFieldValue == null) {return null;}if (sourceFieldValue instanceof Color) {return sourceFieldValue.toString();} if (sourceFieldValue instanceof String && destinationClass.equals(Color.class)) {try {return Color.newInstance((String)sourceFieldValue);} catch (Exception e) {e.printStackTrace();}} else{throw new MappingException("Converter EnumColorCustomConverter "+ "used incorrectly. Arguments passed in were:"+ sourceFieldValue);}return null;} }
<mapping><class-a>com.aabond.entity.Flower</class-a><class-b>com.aabond.entity.FlowerVo</class-b><field><a >purchaseDate</a><b date-format="yyyy-MM-dd HH:mm:ss">purchaseDateStr</b></field><field custom-converter="com.aabond.converter.EnumColorCustomConverter"><a>color</a><b>colorStr</b></field> </mapping>
@Test public void testDozer() {Flower flower = new Flower();flower.setId(1);flower.setPurchaseDate(new Date());flower.setColor(Color.RED);FlowerVo f = DozerUtil.map(flower, FlowerVo.class);System.out.println(f);//assertThat(map, isA(Flower.class));}
更多配置
关于XML配置,更详细信息可以查看官方文档,下面介绍一些常用的配置Date和String 全局映射
<mappings><configuration><date-format>yyyy-MM-dd HH:mm:ss</date-format><!-- more --></configuration> </mappings>
遇到错误策略 默认true
<stop-on-errors>true</stop-on-errors>
同名属性映射 默认true
<wildcard>true</wildcard>
字符串Trim
<trim-strings>false</trim-strings>
全局自定义转换器
<custom-converters> <converter type="org.dozer.converters.TestCustomConverter" ><class-a>org.dozer.vo.TestCustomConverterObject</class-a><class-b>another.type.to.Associate</class-b></converter> </custom-converters>
null值不映射
<field map-null="false"><a>oneFoo2</a><b>oneFooPrime2</b> </field>
单项映射
dozer默认是双向映射,可以通过配置改成单项映射支持字段单项映射
<field type="one-way"><a>oneFoo2</a><b>oneFooPrime2</b> </field>
支持类单项映射
<mapping type="one-way"> </mapping>
复制引用
Dozer支持复制引用
<field copy-by-reference="true"><a>copyByReference</a><b>copyByReferencePrime</b> </field>
支持全局配置
<configuration><copy-by-references><copy-by-reference>com.github.dozermapper.core.vo.NoExtendBaseObjectGlobalCopyByReference</copy-by-reference></copy-by-references> </configuration>
参考:
https://blog.csdn.net/u012534326/article/details/102611483
http://dozer.sourceforge.net/dozer-user-guide.pdf
https://dozermapper.github.io/gitbook/
SpringBoot学习小结之Dozer相关推荐
- SpringBoot学习小结之Redis
文章目录 前言 一.SpringBoot使用Redis 1.1 pom依赖 1.2 两种连接方案 1.3 配置 1.4 简单使用 二.各种场景 2.1 缓存数据 2.2 分布式锁 2.2.1 通过se ...
- SpringBoot学习小结之Elasticsearch
文章目录 一.Elasticsearch 1.1 用途 1.2 和Apache solr对比 1.3 基本概念 1.4 基本使用 1.5 Java API 二.SpringBoot 2.1 版本 2. ...
- SpringBoot(学习笔记)
SpringBoot学习笔记 从今天开始就进入微服务阶段 一些小问题 1.HelloWorld 1.1回顾什么是Spring 1.2什么是SpringBoot 1.3微服务架构 2.第一个Spring ...
- Springboot学习笔记(二)Web开发
前言: 学习B站UP主狂神说视频笔记整理视频链接 狂神笔记链接 上篇笔记链接-Springboot学习笔记(一)快速上手 Web开发 静态资源 在以往的SpringMVC中所有静态资源或者页面应该放在 ...
- springboot学习文档
SpringBoot学习文档 首先真的特别感谢同学的分享以及老师的整理,让我成功入门了springboot的. 一.介绍 小结: - SpringBoot并不是一个新的开发语言- Spring Boo ...
- SpringBoot 学习笔记
SpringBoot 学习笔记 文章目录 SpringBoot 学习笔记 1. SpringBoot简介 1.1 什么是Spring 1.2 Spring 是如何简化Java开发的 1.3 什么是 S ...
- 狂神说——SpringBoot学习
spring官网 SpringBoot官网 spring-security版本下载 狂神官网学习 也可以搜索B站 (狂神说) 学习网站:https://www.bilibili.com/video/B ...
- Python - 输出格式 (学习小结)
Python - 输出格式 (学习小结) Bu.xing 利用现代手段,创建学习家园 关注他 1 人赞同了该文章 Python 输出格式 我们常说的输出格式分两种含义: # 一种是指数据在屏幕上的显 ...
- Page 的生命周期学习小结
(以前我在 csdn 写的翻译文章,现在转到这里来.) Page 的生命周期学习小结 原文链接:Page Events: Order and PostBack 作者:Paul Wilson 翻译:木野 ...
最新文章
- ImportError: cannot import name ‘DtypeArg‘ from ‘pandas
- oschina多媒体工具
- centos下升级glib
- Python第三章-字符串
- STM32外部中断与各通道对应关系
- 【♻️markdown之一次编写,到处使用♻️】markdown文件转word
- C 图像处理 颜色相关宏定义
- JS转字符 判断数字等
- 6.23 NIUDAY 深圳站 | 从新零售到金融,Follow 技术大咖一起探索人工智能应用的无限可能...
- 远程仓库---从远程库克隆
- 相同Ip 不同端口配置Nginx反向代理Apache
- 微软服务器系统桌面无图标,开机桌面没有图标的几种解决方法
- 关闭rhel 6.5的selinux
- 运动目标跟踪(一)--搜索算法预测模型之KF,EKF,UKF
- Linux系统编程 -- 死锁
- 手动方式安装 eclipse 的svn插件 Subversive和 Subversive SVN Connectors
- [wordpress搬家]马来西亚 你好
- android空间深度清理,安卓手机垃圾深度清理技巧
- unity学习、unity培训、unity企业培训、U3D资源、U3D培训视频U3D教程、U3D常见问题、U3D项目源码
- iOS 系统方法获取当前位置经纬度
热门文章
- 安装到树莓派c语言编程ide,【玩树莓】编程篇(四)在树莓派2上运行Cloud9 IDE服务器...
- 树莓派的GPIO编程
- 如何将微课应用到计算机教学,如何将微课应用于高校计算机教学中
- Unity音频采样器(用于Unity音乐可视化)
- python打包中文报错,解决python3+Gooey使用pyinstaller打包时无法输出中文的问题
- 阿里系utdid和友盟冲突解决方案
- 工作感悟-窝囊男人的特点
- 密码学实验_8_本原根计算(python 实现)
- UE4 蓝图编程官网初级练习目录
- 星际官方小说:《刀锋女王》