Hibernate的beanutils 深拷贝.copyProperties方法,怎么不能拷贝对象

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&项目(18)
在import org.springframework.beans.BeanU包下:
&span style=&white-space:pre&& &/span&//赋值vo对象的值到po中&span style=&white-space:pre&& &/span&/**&span style=&white-space:pre&& &/span&* &span style=&font-family: Arial, Helvetica, sans-&&&span style=&color:#ff0000;&&BeanUtils.copyProperties(source, target);&/span& 这是文档提示!&/span&&span style=&font-family: Arial, Helvetica, sans-&&&span style=&white-space:pre&& &/span&
&span style=&color:#ff0000;&&VO对象,PO对象&/span&&/span&&span style=&white-space:pre&& &/span&*/
&span style=&font-family: Arial, Helvetica, sans-&&BeanUtils.copyProperties(this.getModel(),sysUserGroup);&/span& //BeanUtils.copyProperties(SysUserGroupForm(vo对象), sysUserGroup(po对象);
在import mons.beanutils.BeanU包下:
&span style=&white-space:pre&& &/span&//VO---&PO&span style=&white-space:pre&& &/span&/**&span style=&white-space:pre&& &/span&*
&span style=&font-family: Arial, Helvetica, sans-&&&span style=&color:#cc0000;&&BeanUtils.copyProperties(dest, orig); &/span&这是文档提示!&/span&&span style=&white-space:pre&& &/span&*&span style=&white-space:pre&&
&span style=&color:#ff0000;&& PO对象,VO对象&/span&&span style=&white-space:pre&& &/span&*/ BeanUtils.copyProperties(sysUser, sysUserForm);
在项目中,时间转换可以这样:
属于:import mons.lang.time.DateFormatU包下:
String curDate = DateFormatUtils.format(new java.util.Date(), &yyyy-MM-dd HH:mm:ss&);
用方法的时候,一定要注意包!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:34470次
积分:1714
积分:1714
排名:第16476名
原创:135篇
转载:41篇
(1)(1)(1)(19)(8)(9)(7)(1)(2)(6)(4)(14)(17)(20)(15)(38)(11)(2)一、简介:&&&&&&&&BeanUtils提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度。
二、用法:
&&&&&&&&如果你有两个具有很多相同属性的JavaBean,一个很常见的情况就是Struts里的PO对象(持久对象)和对应的ActionForm。例如:一个用户注册页面,有一个User实体类和一个UserActionForm,我们一般会在Action里从ActionForm构造一个PO对象,传统的方式是使用类似下面的语句对属性逐个赋值:
// 获取 ActionForm 表单数据
UserActionForm uForm = (UserActionForm)
// 构造一个User对象
User user = new User();
// 逐一赋值
user.setUsername(uForm.getUsername);
user.setPassword(uForm.getPassword);
user.setAge(uForm.getAge);
...........
...........
// 然后调用JDBC、或操作Hibernate 持久化对象User到数据库
通过这样的方法如果表单数据N多、100、1000(夸张点。哈哈)、、、、那我们不是要写100、、、1000行set、get了。谁都不愿意这样做。
而我们使用 BeanUtils.copyProperties() 方法以后,代码量大大的减少,而且整体程序看着也简洁明朗,代码如下:
// 获取 ActionForm 表单数据
UserActionForm uForm = (UserActionForm)
// 构造一个User对象
User user = new User();
BeanUtils.copyProperties(user, uForm);
// 然后调用JDBC、或操作Hibernate 持久化对象User到数据库
很方便是吧。
注:如果User和UserActionForm&间存在名称不相同的属性,则BeanUtils不对这些属性进行处理,需要手动处理。例如:
User类里面有个createDate 创建时间字段,而UserActionForm里面无此字段。BeanUtils.copyProperties()不会对此字段做任何处理。必须要自己手动处理。
还有个注意的地方是,貌似UserActionForm里面不能带有时间类型的属性,比如Date,Timestamp、、、我调试的时候就会报错。可能是我技术问题、呵呵。
第一次写blog、有说不对的地方希望各位大虾多多指点。在此谢过了
博文原址:/blog/361954
阅读(...) 评论()Java web(8)
转自:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp37
性能对比: BeanCopier & PropertyUtils & BeanUtils. 其中BeanCopier的性能高出另外两个100数量级。
BeanCopier使用可参考:&
对象拷贝的应用现状简介:
业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最安全的做法,但是当数据对象的属性字段数量超过程序员的容忍的程度,代码因此变得臃肿不堪,使用一些方便的对象拷贝工具类将是很好的选择。
目前流行的较为公用认可的工具类:
Apache的两个版本:(反射机制)
mons.beanutils.PropertyUtils.copyProperties(Object dest, Object orig)
mons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)
Spring版本:(反射机制)
org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable, String[] ignoreProperties)
cglib版本:(使用动态代理,效率高)
net.sf.cglib.beans.BeanCopier.copy(Object paramObject1, Object paramObject2, Converter paramConverter)
反射类型:(apache)
都使用静态类调用,最终转化虚拟机中两个单例的工具对象。
public&BeanUtilsBean()
&&this(new&ConvertUtilsBean(),&new&PropertyUtilsBean());
ConvertUtilsBean可以通过ConvertUtils全局自定义注册。
ConvertUtils.register(new DateConvert(), java.util.Date.class);
PropertyUtilsBean的copyProperties方法实现了拷贝的算法。
1、& 动态bean:orig instanceof DynaBean:Object value = ((DynaBean)orig).get(name);然后把value复制到动态bean类
2、& Map类型:orig instanceof Map:key&#20540;逐个拷贝
3、& 其他普通类::从beanInfo【每一个对象都有一个缓存的bean信息,包含属性字段等】取出name,然后把sourceClass和targetClass逐个拷贝Cglib类型:BeanCopier
copier = BeanCopier.create(source.getClass(), target.getClass(), false);
copier.copy(source, target, null);
Create对象过程:产生sourceClass-》TargetClass的拷贝代理类,放入jvm中,所以创建的代理类的时候比较耗时。最好保证这个对象的单例模式,可以参照最后一部分的优化方案。
创建过程:源代码见jdk:net.sf.cglib.beans.BeanCopier.Generator.generateClass(ClassVisitor)
1、& 获取sourceClass的所有public get 方法-》PropertyDescriptor[] getters
2、& 获取TargetClass 的所有 public set 方法-》PropertyDescriptor[] setters
3、& 遍历setters的每一个属性,执行4和5
4、& 按setters的name生成sourceClass的所有setter方法-》PropertyDescriptor getter【不符合javabean规范的类将会可能出现空指针异常】
5、& PropertyDescriptor[] setters-》PropertyDescriptor setter
6、& 将setter和getter名字和类型 配对,生成代理类的拷贝方法。
Copy属性过程:调用生成的代理类,代理类的代码和手工操作的代码很类&#20284;,效率非常高。
你不知道这些陷阱吧?
Apache- PropertyUtils
Apache- BeanUtils
Spring- &BeanUtils
BeanCopier
是否可以扩展
useConvete功能
Yes,但比较难用
(sourceObject,targetObject)的顺序
对sourceObject特殊属性的限制:(Date,BigDecimal等)【见备注1】
NO,异常出错
相同属性名,且类型不匹配时候的处理
【见备注2】
异常,拷贝部分属性,非常危险
OK,并能进行初级转换,Long和Integer互转
异常,拷贝部分属性
OK,但是该属性不拷贝
Get和set方法不匹配的处理
【见备注3】
创建拷贝的时候报错,无法拷贝任何属性(当且仅当sourceClass的get方法超过set方法)
对targetObject特殊属性的限制:(Date,BigDecimal等)
原因:dateTimeConveter的conveter没有对null&#20540;的处理
public class&ErrorBeanUtilObject {&//此处省略getter,setter方法
&&&&private&String&name;
&&&&private&java.util.Date&date;
&public class&ErrorBeanUtilsTest { &
&&&&public static void&main(String args[])&throws&Throwable& {&&
&&& ErrorBeanUtilObject from =&new&ErrorBeanUtilObject();&
&&& ErrorBeanUtilObject to =&new&ErrorBeanUtilObject();&&
&&& //from.setDate(new&java.util.Date());
&&& from.setName(&TTTT&);
&&& mons.beanutils.BeanUtils.copyProperties(to, from);//如果from.setDate去掉,此处出现conveter异常
&&& System.out.println(ToStringBuilder.reflectionToString(from));
&&& System.out.println(ToStringBuilder.reflectionToString(to));
相同属性名,且类型不匹配时候的处理
原因:这两个工具类不支持同名异类型的匹配 !!!【包装类Long和原始数据类型long是可以的】
public class&TargetClass {&&//此处省略getter,setter方法
&&&&private&L&&
&&&&private&S
public class&TargetClass {&&//此处省略getter,setter方法
&&&&private&L
&&&&private&S
public class&ErrorPropertyUtilsTest {&& && &&
&&&&public static void&main(String args[])&throws&IllegalAccessException, InvocationTargetException, NoSuchMethodException& {&&
&&&&&&& SourceClass from =&new&SourceClass();&&
&&&&&&& from.setNum(1);
&&&&&&& from.setName(&name&);&
&&&&&&& TargetClass to =&new&TargetClass();&&
&&&&&&& mons.beanutils.PropertyUtils.copyProperties(to, from); //抛出参数不匹配异常
&&&&&&& org.springframework.beans.BeanUtils.copyProperties(from, to);
//抛出参数不匹配异常
&&&&&&& System.out.println(ToStringBuilder.reflectionToString(from));&&&&
&&&&&&& System.out.println(ToStringBuilder.reflectionToString(to));&&
Get和set方法不匹配的处理
public class&ErrorBeanCopierTest {& &&
&&& &* 从该用例看出BeanCopier.create的target.class 的每一个get方法必须有队形的set方法
&&& &*&@param&args
&&&&public static void&main(String args[]) {&&
&&&&&&& BeanCopier copier = BeanCopier.create(UnSatifisedBeanCopierObject.class, SourceClass.class,false);
&&&&&&& copier = BeanCopier.create(SourceClass.class, UnSatifisedBeanCopierObject.class,&false); //此处抛出异常创建&
class&UnSatifisedBeanCopierObject {&&&
&&&&private&S
&&&&private&L
&&&&public&String getName() {
&&&&&&&return&
&&&&public void&setName(String name) {
&&&&&&&this.name =
&&&&public&Long getNum() {
&&&&&&&return&
//& public void setNum(Long&num) {
//&&&& this.num =&num;
一些优化和改进
增强apache的beanUtils的拷贝属性,注册一些新的类型转换
public class BeanUtilsEx extends BeanUtils
& public static void copyProperties(Object dest, Object orig)
&&&&& BeanUtils.copyProperties(dest, orig);
&&& } catch (IllegalAccessException ex) {
&&&&& ex.printStackTrace();
&&& } catch (InvocationTargetException ex) {
&&&&& ex.printStackTrace();
&&& ConvertUtils.register(new DateConvert(), java.util.Date.class);
&&& ConvertUtils.register(new DateConvert(), java.sql.Date.class);
&&& ConvertUtils.register(new BigDecimalConvert(), BigDecimal.class);
将beancopier做成静态类,方便拷贝
public class&BeanCopierUtils {
&&&&&public static&Map&String,BeanCopier&&beanCopierMap&=&new&HashMap&String,BeanCopier&();
&&&&&public static void&copyProperties(Object source, Object target){
&&&&&&&& String beanKey =&&generateKey(source.getClass(), target.getClass());
&&&&&&&& BeanCopier copier =&&null;
&&&&&&&&&if(!beanCopierMap.containsKey(beanKey)){
&&&&&&&&&&&&& copier = BeanCopier.create(source.getClass(), target.getClass(),&false);
&&&&&&&&&&&&&&beanCopierMap.put(beanKey, copier);
&&&&&&&& }else{
&&&&&&&&&&&&& copier =&beanCopierMap.get(beanKey);
&&&&&&&& }
&&&&&&&& copier.copy(source, target,&null);
&&&&&private static&String generateKey(Class&?& class1,Class&?&class2){
&&&&&&&&&return&class1.toString() &#43; class2.toString();
修复beanCopier对set方法强限制的约束
改写net.sf.cglib.beans.BeanCopier.Generator.generateClass(ClassVisitor)方法
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
预先存一个names2放入
/* 109 */&&&&&& Map names2 =&new&HashMap();
/* 110 */&&&&&&&for&(int&i = 0; i & getters. &#43;&#43;i) {
/* 111 */&&&&&&&& names2.put(setters[i].getName(), getters[i]);
/*&&&& */&&&&&& }
调用这行代码前判断查询下,如果没有改writeMethod则忽略掉该字段的操作,这样就可以避免异常的发生。
特别说明:尊重作者的劳动成果,转载请注明出处哦~~~
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:23451次
排名:千里之外
原创:39篇
评论:16条
(3)(1)(1)(3)(6)(7)(6)(6)(1)(3)(1)(6)BeanUtils.copyProperties在拷贝属性时忽略空值_小组_ThinkSAAS
BeanUtils.copyProperties在拷贝属性时忽略空值
BeanUtils.copyProperties在拷贝属性时忽略空值
最近在写一个小玩意的时候,需要在两个对象之间拷贝属性
BeanUtils.copyProperties
可是,有一个问题
就是当src对象的键值为Null时
就会把target对象的对应键值覆盖成空了
所以找了下面的这个方式来解决
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set&String& emptyNames = new HashSet&String&();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
public static void copyPropertiesIgnoreNull(Object src, Object target){
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
官方1群:【已满】
让ThinkSAAS更好,把建议拿来。
关注微信,更好学习

我要回帖

更多关于 beanutils 深拷贝 的文章

 

随机推荐