业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最安全的做法,但是当数据对象的属性字段数量超过程序员的容忍的程度比如通常超过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] 566. Reshape the Matrix_Easy

    In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new o ...

  2. js贪心算法---钱币找零问题

    function MinCoinChange(coins){ var coins = coins.sort(function(a,b){ return b - a; }); this.makeChan ...

  3. 要求根据RandomStr.java:使用类型转换生成六位验证字符串,示例程序每次运 行时,都会生成不同的字符串。

    1.程序设计思想验证码 ①定义一个字符串变量来保存随机生成的. ②利用循环产生六位随机数,在产生每一位时将其转换为char类型并写在字符串后面. ③利用对话框显示生成的验证码,并提示用户输入验证码. ...

  4. ROC曲线,AUC面积

    AUC(Area under Curve):Roc曲线下的面积,介于0.1和1之间.Auc作为数值可以直观的评价分类器的好坏,值越大越好. 首先AUC值是一个概率值,当你随机挑选一个正样本以及负样本, ...

  5. Python对list列表及子列表进行排序

    python代码,对list进行升序排序,所有子列表也要进行排序 def iterList(listVar): listVar = sorted(listVar) for i,v in enumera ...

  6. 字符串ASCII码排序

    在对接第三方支付渠道的时候,第三方会要求参数按照ASCII码从小到大排序. 如下是渠道方有关生成签名规则的java代码示例: //初始化0010merkey.private文件: String mer ...

  7. UVa 202 Repeating Decimals(抽屉原理)

    Repeating Decimals 紫书第3章,这哪是模拟啊,这是数论题啊 [题目链接]Repeating Decimals [题目类型]抽屉原理 &题解: n除以m的余数只能是0~m-1, ...

  8. CSS笔记之Grid网格系统

    Grid布局已经不是新鲜的技术了,但一直都是使用了Flex布局,如今需要了边学习边做些常用的笔记.首先grid和flex一样都不支持IE10以下的浏览器 基本布局: 一般是所有子元素都横向排列或者都纵 ...

  9. MongoDB 在 windows 下的安装与服务配置

    本文转载地址: https://blog.csdn.net/Dorma_Bin/article/details/80851230 本地安装及网页测试 在官网下载最新的安装文件 下载地址 : https ...

  10. tp连贯操作

    链接数据库 首先写配置文件 复制concentration.php中的 /* 数据库设置 */ 'DB_TYPE' => '', // 数据库类型 'DB_HOST' => '', // ...