应用场景:
在做修改操作时,需要根据ID加载整个对象,然后一个一个赋值到对象中,然后进行save操作。
在字段比较少的情况下,还是比较快的,如果字段比较多,就比较繁琐,需要一个一个set对应的字段。
举个例子:
比如一个表有20个字段,如果这20个字段都修改过,则在Service需要对这20个字段进行更新操作,一种做法是load出整个对象,然后一个一个值设置到对应的字段中。这样做当然没错,但是多了些比较无聊的事情,需要20行代码进行赋值。然后进行更新。20个还好,如果一个表中有50个字段。那就得50行。故为了这个事情,写了个值拷贝的方法。把新值放到对象中,然后把新值对象拷贝至旧值对象进行值对象的拷贝。现把这个共享出来。
/**
* ObjectUtils.java
* create on 2011-01-01
*/
import java.lang.reflect.Field;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.lang.StringUtils;
/**
* Bean相关操作处理工具类
* @since version1.0
* @author liuhaixiao
*/
@SuppressWarnings("rawtypes")
public class ObjectUtils {
/**
* 根据传入的cls复制整个对象的属性值到另外一个对象的对应的同名和同类型的属性(只复制cls存在的且属同名和同类型的属性值,名为sguid的属性不拷贝)
* @param vo<Object> 源值对象
* @param target<Object> 目标对象
* @param cls<Class> 被拷贝值的对象类型
* @param not_copy<String> 用于指定不拷贝值的属性,可传多个属性名,之间用逗号隔开
* @return void
*/
private static void copyObjectValue(Object vo, Object target, Class cls, String not_copy, boolean isCopyNull){
int flag=0;
if(StringUtils.isNotBlank(not_copy)){
not_copy=","+not_copy+",";//前后加逗号是为了后面能够准确的判断所包含的属性名称
}
try{
String sname = "";
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
sname = fields[i].getName();
//如果属性为id或属性名存在于not_copy指的属性名范围中,则不拷贝访属性值
if(sname.toLowerCase().equals("id") || (StringUtils.isNotBlank(not_copy) && not_copy.indexOf(","+sname+",")!=-1))
continue;
if(fields[i].getType().toString().startsWith("class")
&& !fields[i].getType().getName().equals("java.lang.String")){ //对象类型字段值拷贝
try{
BeanUtils.setProperty(target, sname,
MethodUtils.invokeMethod(vo,"get"+sname.substring(0, 1).toUpperCase()+sname.substring(1),null));
}catch(Exception ne){
flag=1;
continue;
}
}else{ //基本类型字段值拷贝
try{
if(isCopyNull==false && BeanUtils.getProperty(vo, sname)==null){
continue;
}else{
BeanUtils.setProperty(target, sname, BeanUtils.getProperty(vo, sname));
}
}catch(Exception ne){
flag=1;
continue;
}
}
}
}catch(Exception e){
flag=1;
e.printStackTrace();
}
if(flag==1){
flag=0;
System.gc();
}
}
/**
* 复制整个对象的属性值到另外一个对象的对应的同名和同类型的属性
* @param vo<Object> 源值对象
* @param target<Object> 目标对象
* @return void
*/
public static void copyObjValue(Object vo, Object target){
Class cls=vo.getClass();
while(!cls.getName().equals("java.lang.Object")){
copyObjectValue(vo, target, cls, null, false);
cls=cls.getSuperclass();
}
}
/**
* 复制整个对象的属性值到另外一个对象的对应的同名和同类型的属性
* @param vo<Object> 源值对象
* @param target<Object> 目标对象
* @param isCopyNull<boolean> 是否拷贝NULL值
* @return void
*/
public static void copyObjValue(Object vo, Object target, boolean isCopyNull){
Class cls=vo.getClass();
while(!cls.getName().equals("java.lang.Object")){
copyObjectValue(vo, target, cls, null, isCopyNull);
cls=cls.getSuperclass();
}
}
/**
* 复制整个对象的属性值到另外一个对象的对应的同名和同类型的属性,但名为sguid的属性不拷贝
* @param vo<Object> 源值对象
* @param target<Object> 目标对象
* @param not_copy<String> 用于指定不拷贝值的属性,可传多个属性名,之间用逗号隔开
* @return void
*/
public static void copyObjValue(Object vo, Object target, String not_copy){
Class cls=vo.getClass();
while(!cls.getName().equals("java.lang.Object")){
copyObjectValue(vo, target, cls, not_copy, false);
cls=cls.getSuperclass();
}
}
/**
* 复制整个对象的属性值到另外一个对象的对应的同名和同类型的属性,但名为sguid的属性不拷贝
* @param vo<Object> 源值对象
* @param target<Object> 目标对象
* @param not_copy<String> 用于指定不拷贝值的属性,可传多个属性名,之间用逗号隔开
* @param isCopyNull<boolean> 是否拷贝NULL值
* @return void
*/
public static void copyObjValue(Object vo, Object target, String not_copy, boolean isCopyNull){
Class cls=vo.getClass();
while(!cls.getName().equals("java.lang.Object")){
copyObjectValue(vo, target, cls, not_copy, isCopyNull);
cls=cls.getSuperclass();
}
}
}
具体使用方法如下:
把新的对象中的值复制到旧的对象中。
public void update(B new, String id) {
A old = Dao.get(id);
ObjectUtils.copyObjValue(new, old);
}
很好用,谁用谁知道。