业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最安全的做法,但是当数据对象的属性字段数量超过程序员的容忍的程度比如通常超过5个属性的时候,代码因此变得臃肿不堪,使用一些方便的对象拷贝工具类将是很好的选择。

目前流行的较为公用认可的工具类:

Apache的两个版本:(反射机制)

org.apache.commons.beanutils.PropertyUtils.copyProperties(Object dest, Object orig)

org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)

Spring版本:(反射机制)

org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable, String[] ignoreProperties)

新版本的spring也集成了cglib版:org.springframework.cglib.beans.BeanCopier

cglib版本:(使用动态代理,效率高)

net.sf.cglib.beans.BeanCopier.copy(Object paramObject1, Object paramObject2, Converter paramConverter)

dozer版本(xml配置映射,性能最低下):

org.dozer.DozerBeanMapper.map(Object source, Class<T> destinationClass)

就API而言,使用哪个工具类无所谓,我们通常关心两点,功能完善性以及性能。

性能测试:

// 源POJO
package tf56.lf.lfbase.model.dto; import java.io.Serializable; import tf56.lf.lfbase.model.domain.LfProduct; /**
* ClassName:ProductDTO
*
* @version 1.0
* @since v1.0
* @Date 2017年6月19日 yuebiao.wu
*/ public class ProductDTO extends LfProduct implements Serializable{ private static final long serialVersionUID = -1296801547926874402L; } // 目标POJO
package tf56.lf.lfbase.model.domain; import java.io.Serializable;
import java.util.Date; import lombok.Getter;
import lombok.Setter; /**
* ClassName:Product
*
* @author tool
* @version 1.0
* @since v1.0
* Date Jun 26, 2017 2:40:42 PM
*/
@Getter
@Setter
public class LfProduct implements Serializable { private static final long serialVersionUID = 4054863309367744108L; /* 产品id */
private String lfProductId;
/* 物流金融账号 */
private String lfAccountId;
/* 产品名称 */
private String productName;
/* 产品类型(BAOFU:保付; MIAOFU:秒付; JISHIFU:即时付;) */
private String productType;
/* 适用场景列表(逗号分隔)(COD:代收货款; FREIGHT:运费;) */
private String sceneTypes;
/* 产品描述 */
private String productDescription;
/* 产品规则描述 */
private String productRoleDescription;
/* 放款触发行为 */
private String loanAction;
/* 收款触发行为 */
private String repayAction;
/* 产品状态(ENABLE:启用; DISABLE:停用;) */
private String productStatus;
/* 预警阀值 */
private Long warnBalance;
/* 发货人是否控制额度(1:是; 0:否;) */
private Integer isConsignerCreditLimit;
/* 承运商是否控制额度(1:是; 0:否;) */
private Integer isExpressCreditLimit; private String productAgreementUrl; private String poundageCalcType; private String poundageRate; /* 备注1 */
private String remark1;
/* 操作员编号 */
private String operatorId;
/* 输入日期 */
private Date inputDate;
/* 记录更新时间 */
private Date stampDate; }

BeanCopier

        Mapper wrapper = new DozerBeanMapper();
ProductDTO pdt = new ProductDTO();
pdt.setIsConsignerCreditLimit(3);
pdt.setLoanAction("323f3");
pdt.setProductName("feiwefe");
pdt.setPoundageRate("f332r3");
long beg = System.currentTimeMillis();
PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false);
for (int i=0;i<1000;i++) {
LfProduct lfPdt = new LfProduct();
// try {
// try {
// bean.copyProperties(lfPdt, pdt);
// } catch (IllegalAccessException | InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// } catch (NoSuchMethodException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
copier.copy(pdt, lfPdt, null);
if (i==3) {
// System.out.println(JacksonHelper.toJSON(lfPdt));
}
// lfPdt = wrapper.map(pdt, LfProduct.class);
lfPdt.setInputDate(new Date());
}
System.out.println(System.currentTimeMillis() - beg);

大约140ms左右。

        Mapper wrapper = new DozerBeanMapper();
ProductDTO pdt = new ProductDTO();
pdt.setIsConsignerCreditLimit(3);
pdt.setLoanAction("323f3");
pdt.setProductName("feiwefe");
pdt.setPoundageRate("f332r3");
long beg = System.currentTimeMillis();
PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false);
for (int i=0;i<1000;i++) {
LfProduct lfPdt = null;
// try {
// try {
// bean.copyProperties(lfPdt, pdt);
// } catch (IllegalAccessException | InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// } catch (NoSuchMethodException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// copier.copy(pdt, lfPdt, null);
if (i==3) {
// System.out.println(JacksonHelper.toJSON(lfPdt));
}
lfPdt = wrapper.map(pdt, LfProduct.class);
lfPdt.setInputDate(new Date());
}
System.out.println(System.currentTimeMillis() - beg);

2500ms。

PropertyUtilsBean

        Mapper wrapper = new DozerBeanMapper();
ProductDTO pdt = new ProductDTO();
pdt.setIsConsignerCreditLimit(3);
pdt.setLoanAction("323f3");
pdt.setProductName("feiwefe");
pdt.setPoundageRate("f332r3");
long beg = System.currentTimeMillis();
PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false);
for (int i=0;i<1000;i++) {
LfProduct lfPdt = new LfProduct();
try {
try {
bean.copyProperties(lfPdt, pdt);
} catch (IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// copier.copy(pdt, lfPdt, null);
if (i==3) {
// System.out.println(JacksonHelper.toJSON(lfPdt));
}
// lfPdt = wrapper.map(pdt, LfProduct.class);
lfPdt.setInputDate(new Date());
}
System.out.println(System.currentTimeMillis() - beg);

240ms左右。

所以,因为绝大部分都是简单的复制拷贝,这种情况下,BeanCopyer>PropertyUtils>Dozer。

参考:

http://blog.csdn.net/jianhua0902/article/details/8155368

http://blog.csdn.net/liangrui1988/article/details/41802275

java bean属性拷贝工具类比对(性能+功能)的更多相关文章

  1. 对象属性拷贝工具类大全==>Bean的属性拷贝从此不用愁

    大家在做java开发时,肯定会遇到api层参数对象传递给服务层,或者把service层的对象传递给dao层,他们之间又不是同一个类型对象,但字段又是一样,如果还是用普通的get.set方式来处理话,比 ...

  2. 一个Bean属性拷贝的工具类

    package com.fpi.spring.qaepb.cps.util; import java.beans.IntrospectionException; import java.beans.P ...

  3. java bean对象拷贝

    Java的bean的属性复制,大家可以都看一下. 谈谈Java开发中的对象拷贝http://www.wtnull.com/view/2/e6a7a8818da742758bcd8b73d49d6be2 ...

  4. java Bean的映射工具

    数据层,业务逻辑层和表现层,每一层对应的应该是不一样的对象,所以就有个这么个java bean的映射工具 dozer.......................................... ...

  5. Github 开源:高效好用的对象间属性拷贝工具:升讯威 Mapper( Sheng.Mapper)

    Github 地址:https://github.com/iccb1013/Sheng.Mapper 对象属性值映射/拷贝工具.不需要创建映射规则,不要求对象类型一致,适用于简单直接的拷贝操作,可以全 ...

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

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

  7. java bean 属性验证框架 valid

    项目介绍 java 开发中,参数校验是非常常见的需求. 但是 hibernate-validator 在使用过程中,依然会存在一些问题. 特性 支持 fluent-validation 支持 jsr- ...

  8. java读取属性配置文件工具类

    import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * * 类: ProU ...

  9. idea中使用插件lombok简化java bean的getter/setter/log等常用功能

    一.安装. 1. 2. 3. 4. . 二.使用 1. 2. 3. 结果分析,如果没有添加@Setter注解,则LombokTest中的student示例无法使用setAge()等方法.使用lombo ...

随机推荐

  1. [LeetCode] 系统刷题5_Dynamic Programming

    Dynamic Programming 实际上是[LeetCode] 系统刷题4_Binary Tree & Divide and Conquer的基础上,加上记忆化的过程.就是说,如果这个题 ...

  2. node-express根据请求,判断PC和移动端

    function getMachine(req) { var deviceAgent = req.headers["user-agent"].toLowerCase(); var ...

  3. Reported time is too far out of sync with master. Time difference of 52692ms > max allowed of 30000ms

    RegionServer与Master的时间不一致造成的.由错误内容可以看出两台机器之间最大的误差时间为30000ms,一旦超过这个值便无法启动. 解决办法:同步RegionServer与Master ...

  4. 已解决(转)关于android - apk(解析错误)解析程序包时出现问题

    如果开发的应用用户较多,那么必须保证应用在多个版本不同的设备上能够正确的运行.这就要求对各个版本比较熟悉,知道在什么版本中加入了什么新的功能或特性.但是Android的版本太多了,是个令人头疼的问题. ...

  5. httpServletResquire 和httpServletResponse

    package com.bjsxt.servlet.request; import java.io.IOException;import javax.servlet.ServletException; ...

  6. mysql数据库表设计小数类型

    float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位)double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有效 ...

  7. InstallShield 读注册表函数 RegDBGetKeyValueEx ()执行失败

    注: rtn = RegDBGetKeyValueEx(szKey, szNumName, nvType, svNumValue, nvSize); 调用失败如果这个函数的几个参数没有初始化的值,调用 ...

  8. CSS3 transition-timing-function 深入理解和技巧

    基础 语法: transition-timing-function : ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier( ...

  9. Thinkphp 框架

    核心函数库:   配置文件:     语言包  :  核心资源库:入口文件 核心配置文件 系统行为目录:功能目录:核心文件:摸板类文件目录

  10. ASP.NET JSON(转http://www.360doc.com/content/14/0615/21/18155648_386887590.shtml)

    概念介绍还是先简单说说Json的一些例子吧.注意,以下概念是我自己定义的,可以参考.net里面的TYPE的模型设计如果有争议,欢迎提出来探讨!1.最简单:{"total":0} t ...