java(如何复制非空对象属性值)

这篇文章主要介绍了java如何复制非空对象属性值的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

java,如何复制非空对象属性值,久久派带你了解更多相关信息。

目录
  • java 复制非空对象属性值
    • 然后封装一下得到以下方法
    • 测试方法就不提供了,自行测试即可
  • java对象属性复制的几种方式
    • 1.使用java反射机制
    • 2.使用spring-beans5.0.8包中的BeanUtils类
    • 3.使用cglib3.2.8包中的net.sf.cglib.beans.BeanCopier类
    • 4.使用spring-core5.0.8包

java 复制非空对象属性值

很多时候,我们需要通过对象拷贝,比如说VO类与数据库实体bean类、更新时非空对象不更新,对同一对象不同数据分开存储等

用于对象拷贝,spring 和 Apache都提供了相应的工具类方法,BeanUtils.copyProperties

但是对于非空属性拷贝就需要自己处理了

在这里借用spring中org.springframework.beans.BeanUtils类提供的方法

copyProperties(Object source, Object target, String… ignoreProperties)

/**     * Copy the property values of the given source bean into the given target bean,     * ignoring the given \"ignoreProperties\".     * <p>Note: The source and target classes do not have to match or even be derived     * from each other, as long as the properties match. Any bean properties that the     * source bean exposes but the target bean does not will silently be ignored.     * <p>This is just a convenience method. For more complex transfer needs,     * consider using a full BeanWrapper.     * @param source the source bean     * @param target the target bean     * @param ignoreProperties array of property names to ignore     * @throws BeansException if the copying failed     * @see BeanWrapper     */    public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {        copyProperties(source, target, null, ignoreProperties); /**     * Copy the property values of the given source bean into the given target bean.     * <p>Note: The source and target classes do not have to match or even be derived     * from each other, as long as the properties match. Any bean properties that the     * source bean exposes but the target bean does not will silently be ignored.     * @param source the source bean     * @param target the target bean     * @param editable the class (or interface) to restrict property setting to     * @param ignoreProperties array of property names to ignore     * @throws BeansException if the copying failed     * @see BeanWrapper     */    private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)            throws BeansException {         Assert.notNull(source, \"Source must not be null\");        Assert.notNull(target, \"Target must not be null\");         Class<?> actualEditable = target.getClass();        if (editable != null) {            if (!editable.isInstance(target)) {                throw new IllegalArgumentException(\"Target class [\" + target.getClass().getName() +                        \"] not assignable to Editable class [\" + editable.getName() + \"]\");            }            actualEditable = editable;        }        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);        List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);         for (PropertyDescriptor targetPd : targetPds) {            Method writeMethod = targetPd.getWriteMethod();            if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());                if (sourcePd != null) {                    Method readMethod = sourcePd.getReadMethod();                    if (readMethod != null &&                            ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {                        try {                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {                                readMethod.setAccessible(true);                            }                            Object value = readMethod.invoke(source);                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {                                writeMethod.setAccessible(true);                            }                            writeMethod.invoke(target, value);                        }                        catch (Throwable ex) {                            throw new FatalBeanException(                                    \"Could not copy property \'\" + targetPd.getName() + \"\' from source to target\", ex);                        }                    }                }            }        }    }

然后封装一下得到以下方法

/**     * @author zml2015     * @Email zhengmingliang911@gmail.com     * @Time 2017年2月14日 下午5:14:25     * @Description <p>获取到对象中属性为null的属性名  </P>     * @param source 要拷贝的对象     * @return     */    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);    }     /**     * @author zml2015     * @Email zhengmingliang911@gmail.com     * @Time 2017年2月14日 下午5:15:30     * @Description <p> 拷贝非空对象属性值 </P>     * @param source 源对象     * @param target 目标对象     */    public static void copyPropertiesIgnoreNull(Object source, Object target) {        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));    }

测试方法就不提供了,自行测试即可

如果项目中使用的框架有Hibernate的话,则可以通过在实体类上添加下面两条注解

@DynamicInsert(true)@DynamicUpdate(true)

如果想对该注解进一步了解的话,那么可以去官网看英文文档,文档解释的很清楚,在此不再赘述了

java对象属性复制的几种方式

1.使用java反射机制

获取对象的属性和get、set方法进行复制;

2.使用spring-beans5.0.8包中的BeanUtils类

import org.springframework.beans.BeanUtils;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();BeanUtils.copyProperties(sourceObject, targetObject);

3.使用cglib3.2.8包中的net.sf.cglib.beans.BeanCopier类

import net.sf.cglib.beans.BeanCopier;import net.sf.cglib.core.Converter;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);--第三个参数表示是否使用转换器,false表示不使用,true表示使用Converter converter = new CopyConverter();--自定义转换器beanCopier.copy(sourceObject, targetObject, converter);

转换器(当源对象属性类型与目标对象属性类型不一致时,使用转换器):

import net.sf.cglib.core.Converter;import org.apache.commons.lang3.StringUtils;import java.math.BigDecimal;import java.util.Date;/** * Created by asus on 2019/7/12. */public class CopyConverter implements Converter {    @Override    public Object convert(Object value, Class target, Object context) {        {            String s = value.toString();            if (target.equals(int.class) || target.equals(Integer.class)) {                return Integer.parseInt(s);            }            if (target.equals(long.class) || target.equals(Long.class)) {                return Long.parseLong(s);            }            if (target.equals(float.class) || target.equals(Float.class)) {                return Float.parseFloat(s);            }            if (target.equals(double.class) || target.equals(Double.class)) {                return Double.parseDouble(s);            }            if(target.equals(Date.class)){                while(s.indexOf(\"-\")>0){                    s = s.replace(\"-\", \"/\");                }                return  new Date(s);            }            if(target.equals(BigDecimal.class)){                if(!StringUtils.isEmpty(s)&&!s.equals(\"NaN\")){                    return  new BigDecimal(s);                }            }            return value ;        }    }}

4.使用spring-core5.0.8包

中的org.springframework.cglib.beans.BeanCopier类(用法与第三种一样)

import org.springframework.cglib.beans.BeanCopier;import org.springframework.cglib.core.Converter;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();Converter converter = new SpringCopyConverter();BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);beanCopier.copy(sourceObject, targetObject, converter);

经过循环复制测试(源对象与目标对象各160个属性):

java(如何复制非空对象属性值)

  • 第一种:Java反射通过判断属性类型,常用类型的属性值都能复制,但是不优化的前提下效率最慢;
  • 第二种:属性类型不同时无法复制,且效率相对较慢;
  • 第三种:耗时最少,不使用转换器时,属性类型不同时无法复制,使用转换器后,耗时会相对变长;
  • 第四种:与第三种相似,但是耗时相对较长;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持趣讯吧。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/19786.html

(0)
nan
上一篇 2021-09-01
下一篇 2021-09-01

相关推荐

发表回复

登录后才能评论