作者:京东零售 张宾

1.Orika是什么?

Orika是一个简单、快速的JavaBean拷贝框架,它能够递归地将数据从一个JavaBean复制到另一个JavaBean,这在多层应用开发中是非常有用的。

2.为什么要引入Orika?

工作中,我们经常需要将对象转换成不同的形式以适应不同的api,或者在不同业务层中传输对象而不同分层的对象存在不同的格式,因此我们需要编写映射代码将对象中的属性值从一种类型转换成另一种类型。

Orika用于简化多层之间的对象映射,避免苦苦挣扎于手工编码和基于反射的映射。Orika关注尽可能地自动化,同时根据需要提供配置和扩展实现定制。

3.项目常用javabean映射技术

Java反射:性能问题、无法解决嵌套javabean映射复制

手工映射:硬编码、代码量大

序列化方式:通过json、xml的序列化和反序列化方式,字段参数不相同时,需要硬编码赋值

4.常用bean映射工具

BeanUtils:apache的BeanUtils和spring的BeanUtils中拷贝方法的原理都是先用jdk中 java.beans.Introspector类的getBeanInfo()方法获取对象的属性信息及属性get/set方法,接着使用反射(Method的invoke(Object obj, Object... args))方法进行赋值。apache支持名称相同但类型不同的属性的转换,spring支持忽略某些属性不进行映射,他们都设置了缓存保存已解析过的BeanInfo信息。

BeanCopier:cglib的BeanCopier采用了不同的方法:它不是利用反射对属性进行赋值,而是直接使用ASM的MethodVisitor直接编写各属性的get/set方法(具体过程可见BeanCopier类的generateClass(ClassVisitor v)方法)生成class文件,然后进行执行。由于是直接生成字节码执行,所以BeanCopier的性能较采用反射的BeanUtils有较大提高。

Orika:底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,因此在速度上比使用反射进行赋值会快很多。Orika支持递归映射,将映射嵌套类直到用“简单”类型完成映射。它还包含故障保险,以正确处理正在尝试映射的对象中的递归引用。

5.如何使用Orika?

5.1 maven依赖

ma.glasnost.orika

orika-core

1.5.2

5.2 两个javabean字段名称相同映射

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

//字段名相同映射

mapperFactory.classMap(Person.class, PersonInfo.class).byDefault().register();

MapperFacade mapperFacade = mapperFactory.getMapperFacade();

Person person = new Person();

person.setFirstName("张");

person.setLastName("三");

PersonInfo personInfo = mapperFacade.map(person, PersonInfo.class);

输出结果:

5.3 两个javabean字段名称不相同映射

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

mapperFactory.classMap(Person.class, PersonDesc.class)

.field("firstName", "givenName").field("lastName", "sirName")

.byDefault() .register();

MapperFacade mapperFacadeDesc = mapperFactory.getMapperFacade();

Person personNew = new Person();

personNew.setFirstName("王");

personNew.setLastName("五");

PersonDesc personDesc = mapperFacadeDesc.map(personNew, PersonDesc.class);

输出结果:

5.4 数组和List映射javabean

public static class PersonNameList {

private List nameList;

public PersonNameList(List nameList) {

this.nameList = nameList;

}

//getter/setter方法

}

mapperFactory.classMap(PersonNameList.class, Person.class)

.field("nameList[0]", "firstName")

.field("nameList[1]", "lastName").register();

List nameParts = Arrays.asList(new String[]{"李", "四"});

Person person = mapperFactory.getMapperFacade().map(new PersonNameList(nameParts), Person.class);

输出结果:

5.5 相同类型javabean复制(原型模式)

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

mapperFactory.classMap(Person.class, Person.class).byDefault().register();

Person person = new Person();

person.setFirstName("张");

person.setLastName("三");

Person personNew = mapperFactory.getMapperFacade().map(person, Person.class);

输出结果:

5.6 嵌套javabean映射

mapperFactory.classMap(Flight.class, Flight.class).byDefault().register();

Cabin cabinY = new Cabin("Y", "8", 1200);

Cabin cabinF = new Cabin("C", "6", 1900);

Cabin cabinC = new Cabin("F", "A", 2400);

Flight flight = new Flight("CA1831", Lists.newArrayList(cabinY, cabinF, cabinC));

Flight flightCopy = mapperFactory.getMapperFacade().map(flight, Flight.class);

System.out.println("原对象:flight=" + JSON.toJSONString(flight));

System.out.println("新对象:flightCopy=" + JSON.toJSONString(flightCopy));

flightCopy.setFlightNo("MU5183");

flightCopy.getCabins().remove(0);

System.out.println("修改航变号和删除舱位:flightCopy=" + JSON.toJSONString(flightCopy)); System.out.println("原对象:flight=" + JSON.toJSONString(flight));

输出结果:

5.7 List类型映射

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

mapperFactory.classMap(Cabin.class, CabinDesc.class).byDefault().register();

Cabin cabinY = new Cabin("Y", "8", 1200);

Cabin cabinF = new Cabin("C", "6", 1900);

Cabin cabinC = new Cabin("F", "A", 2400);

List cabinList = Lists.newArrayList(cabinY, cabinF, cabinC);

List cabinDescList = mapperFactory.getMapperFacade().mapAsList(cabinList, CabinDesc.class);

System.out.println("cabinList = " + JSON.toJSONString(cabinList));

System.out.println("cabinDescList = " + JSON.toJSONString(cabinDescList));

输出结果

5.8 自定义数据类型转化器(String to Date)

继承接口CustomConverter类,覆盖实现convert方法

public static class StringToDateConverter extends CustomConverter<String, Date> {

private String dateFormat;

public StringToDateConverter(String dateFormat) {

this.dateFormat = dateFormat;

}

public Date convert(String s, Type<? extends Date> type, MappingContext mappingContext) {

try {

return DateUtils.parseDate(s, dateFormat);

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

mapperFactory.getConverterFactory()

.registerConverter(new StringToDateConverter("yyyy-MM-dd"));

mapperFactory.classMap(ArrayMapper.PersonNameList.class, Person.class)

.field("nameList[0]", "firstName").field("nameList[1]", "lastName")

.field("nameList[2]", "birthDate").register();

List nameParts = Arrays.asList(new String[]{"李", "四", "1989-10-11"});

Person person = mapperFactory.getMapperFacade().map(new ArrayMapper.PersonNameList(nameParts), Person.class);

System.out.println("nameParts = " + JSON.toJSONString(nameParts));

System.out.println("person = " + JSON.toJSONStringWithDateFormat(person,"yyyy-MM-dd"));

输出结果:

6. 各映射工具的性能测试

每种方法先预热执行20次,而后再执行100000次获取每次执行的平均时间

7.参考文献

官网:http://orika-mapper.github.io/orika-docs/intro.html

其他:https://www.jianshu.com/p/5daf68dc5758

http://tech.dianwoda.com/2017/11/04/gao-xing-neng-te

-xing-feng-fu-de-beanying-she-gong-ju-orika/

Orika JavaBean映射工具使用的更多相关文章

  1. 【代码工具】Orika JavaBean映射工具探秘

    转自:https://www.cnblogs.com/albert1024/articles/8434741.html Orika是一个简单.快速的JavaBean拷贝框架,Orika使用字节代码生成 ...

  2. Orika JavaBean映射工具探秘

    Orika是一个简单.快速的JavaBean拷贝框架,Orika使用字节代码生成来创建具有最小开销的快速映射器. 关于: 作为开发人员,我们必须为业务问题提供解决方案,我们希望利用我们的时间来做真正重 ...

  3. JavaBean映射工具dozer学习

    阅读更多 转载自http://lishaorui.iteye.com/blog/1151513 1.简介     dozer是一种JavaBean的映射工具,类似于apache的BeanUtils.但 ...

  4. 常见Bean映射工具分析评测及Orika介绍

    原地址:http://tech.dianwoda.com/2017/11/04/gao-xing-neng-te-xing-feng-fu-de-beanying-she-gong-ju-orika/ ...

  5. Bean映射工具之Apache BeanUtils VS Spring BeanUtils

    背景 在我们实际项目开发过程中,我们经常需要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不改变源对象的属性信息,比如DTO数据传输对象和数据对象DO,我们需要将DO对象进 ...

  6. Java bean常见映射工具分析和比较

    1. 概述 日常Java开发项目中,我们经常需要将对象转换成其他形式的对象,因此我们需要编写映射代码将对象中的属性值从一种类型转换成另一种类型. 进行这种转换除了手动编写大量的get/set代码,还可 ...

  7. EF架构~AutoMapper对象映射工具简化了实体赋值的过程

    回到目录 AutoMapper是一个.NET的对象映射工具,一般地,我们进行面向服务的开发时,都会涉及到DTO的概念,即数据传输对象,而为了减少系统的负载,一般我们不会把整个表的字段作为传输的数据,而 ...

  8. Java微信公众号开发-外网映射工具配置

    一.开发环境准备 1.一个微信公众号 2.外网映射工具(开发调试)如花生壳.ngrok工具 注:与微信对接的URL要具备以下条件a:在公网上能够访问 b:端口只支持80端口 这里使用ngrok.cc: ...

  9. [转]p2p端口映射工具 dog-tunnel

    [转]p2p端口映射工具 dog-tunnel http://www.oschina.net/p/dog-tunnel 狗洞是一个高速的 P2P 端口映射工具,同时支持Socks5代理. 0.5版后开 ...

  10. 根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第2版)

             目录:                 第1版:http://blog.csdn.net/vipbooks/article/details/51912143              ...

随机推荐

  1. MyBatis batchInsert 批量插入数据

    mybatis 是一个 Java 的持久层框架,它支持定制化 SQL.存储过程以及高级映射.通过 MyBatis,开发者可以直接编写原生态 SQL,避免了 JDBC 代码的繁琐. 如何在 MyBati ...

  2. Xml Entity 实体互转(XStream)

    http://x-stream.github.io/tutorial.html 项目中用了 JAXB 方式 Xml Entity 实体互转(JAXB) 实体: import com.thoughtwo ...

  3. 《Flask Web 开发指南 pt.1》

    最近在看辉哥的<Flask Web 开发实战>,这才有了<Flask Web 开发指南>系列的文章,偏向学习笔记多一点,也有实战的内容 看下这个系列的文章我能写多少篇 :) 愚 ...

  4. SpringBoot 项目实战 | 瑞吉外卖 Day04

    该系列将记录一份完整的实战项目的完成过程,该篇属于第四天 案例来自B站黑马程序员Java项目实战<瑞吉外卖>,请结合课程资料阅读以下内容 该篇我们将完成以下内容: 文件上传下载 新增菜品 ...

  5. Vue3.0 + Element Plus整合实战

    mall-vue3-manage 基于vue3.0 + Element Plus. 整合最新的 Echarts5 强劲的渲染引擎.富文本编辑器 Wangeditor 的后端管理项目. 版本 vue 3 ...

  6. freeswitch的mod_xml_cdr模块

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 在语音呼叫的过程中,话单是重要的计价和结算依据,话单的产生需要稳定可靠,可回溯. fs中的mod_xml_cdr模块提供了基本话单功 ...

  7. python常见面试题讲解(三)明明的随机数

    题目描述 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对 ...

  8. python常见面试题讲解(七)合并表记录

    题目描述 数据表记录包含表索引和数值(int范围的整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出. 输入描述: 先输入键值对的个数然后输入成对的in ...

  9. 基于python安装app

    一.背景 有时候我们在做Android兼容性测试时,经常会使用adb命令一台一台的安装app,比较费事. 二.实现方法 利用python命令行启动web服务器,在手机浏览器输入存放apk包的目录url ...

  10. JavaScrip基本语法

    2. 上篇内容回顾 1. CSS属性 1. 高和宽 2. 字体相关 3. 文本相关 4. 背景相关 1. background-color: red 2. background-image: url( ...