使用 BeanUtils.copyProperties 复制特定字段?

Posted

技术标签:

【中文标题】使用 BeanUtils.copyProperties 复制特定字段?【英文标题】:Copy specific fields by using BeanUtils.copyProperties? 【发布时间】:2011-07-02 01:20:44 【问题描述】:

springframework.beans.BeanUtils 对复制对象非常有用,我经常使用“ignoreProperties”选项。但是,有时我只想复制特定的对象(基本上,与“忽略属性”相反)。有谁知道我该怎么做?任何帮助将不胜感激。

import org.springframework.beans.BeanUtils;

public class Sample     
    public static void main(String[] args)     
        DemoADto demoADto = new DemoADto();
        demoADto.setName("Name of Demo A");
        demoADto.setAddress("Address of Demo A");

        DemoBDto demoBDto = new DemoBDto();

        // This is "ignoreProperties" option
        // But I want to know how I can copy only name field by using BeanUtils or something.
        BeanUtils.copyProperties(demoADto, demoBDto, new String[] "address");

        System.out.println(demoBDto.getName());
        System.out.println(demoBDto.getAddress());    
        


public class DemoADto     
    private String name;    
    private String address;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getAddress() 
        return address;
    

    public void setAddress(String address) 
        this.address = address;
        


public class DemoBDto     
    private String name;    
    private String address;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getAddress() 
        return address;
    

    public void setAddress(String address) 
        this.address = address;
        

【问题讨论】:

【参考方案1】:

看看这个:BeanPropertyCopyUtil。

例子:

copyProperties(user, systemUser, "first firstName", "last lastName");

您还需要 Apache Commons BeanUtils。

【讨论】:

这不是实现此目的的适当方式。如果你的属性名被修改了怎么办?将其作为字符串传递并不是更好的方法,而是使用 Field[] fields = destination.getClass().getDeclaredFields(); 获取所有字段;并遍历 (Field field : fields) //ur copy stuff here 的字段 这不适用于子属性,假设我想忽略所有名称为“id”的属性。【参考方案2】:

如果您不想使用 Commons BeanUtils,您仍然可以通过 BeanWrapper 使用 Spring。

您必须手动循环遍历所有属性,因此您需要创建一个静态辅助方法。

您始终可以复制 copyProperties 正在执行的操作并根据自己的喜好进行调整: http://tinyurl.com/BeanUtils-copyProperties

【讨论】:

【参考方案3】:

您可以使用BeanWrapper 技术。这是一个示例实现:

public static void copyProperties(Object src, Object trg, Iterable<String> props) 

    BeanWrapper srcWrap = PropertyAccessorFactory.forBeanPropertyAccess(src);
    BeanWrapper trgWrap = PropertyAccessorFactory.forBeanPropertyAccess(trg);

    props.forEach(p -> trgWrap.setPropertyValue(p, srcWrap.getPropertyValue(p)));


或者,如果你真的,真的想使用BeanUtils,这里有一个解决方案。反转逻辑,通过将完整属性列表与包含进行比较来收集排除项:

public static void copyProperties2(Object src, Object trg, Set<String> props) 
    String[] excludedProperties = 
            Arrays.stream(BeanUtils.getPropertyDescriptors(src.getClass()))
                  .map(PropertyDescriptor::getName)
                  .filter(name -> !props.contains(name))
                  .toArray(String[]::new);

    BeanUtils.copyProperties(src, trg, excludedProperties);

【讨论】:

BeanWrapper 技术快了 25%。 :) Spring 建议改用PropertyAccessorFactory.forBeanPropertyAccess(Object)。 source 如何获得 Iterable 属性? @kiedysktos Iterable 是一个由 Collection 扩展的接口,所以这个方法会接受任何Collection&lt;String&gt; 关于 BeanWrapper 的提示:使用 trgWrap.setAutoGrowNestedPaths(true) 来避免 NullValueInNestedPathException【参考方案4】:

这是一个带有 Spring BeanUtils 类的示例:

public static void copyList(List sourceList,
        List targetList, Class targetType) 

    try 

        for (Object source : sourceList) 
            Object target = null;
            target = targetType.newInstance();
            BeanUtils.copyProperties(source, target);
            targetList.add(target);
        

     catch (InstantiationException e) 
        e.printStackTrace();
     catch (IllegalAccessException e) 
        e.printStackTrace();
    

【讨论】:

【参考方案5】:

您可以使用 org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable) throws BeansException

确保目标实现可编辑的接口,该接口定义了将被复制的属性。

【讨论】:

【参考方案6】:

beanUtils 有一个重载方法,我们可以在其中传递我们想要忽略的字段数组。

例如。

String[] ignoreProperties= new String[]"field1","field2";

BeanUtils.copyProperties(a, b,ignoreProperties);

【讨论】:

以上是关于使用 BeanUtils.copyProperties 复制特定字段?的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)