扩展BeanUtils功能实现操作List元素属性的拷贝

概述

实际的业务开发过程中,会面对BO, Entity, VO等各种对象。绝大部分场景下前端并不需要那么多的字段,那么当我们从数据库中查询到字段一般得到的是Entity,通常需要减少部分字段并赋值给VO,响应到前端。如果是单个Bean,可以非常方便的使用 BeanUtils.copyProperties(source, target); 来实现,但是对于列表的拷贝并没有提供相应的API,这时候就需要扩展 BeanUtils的功能。

代码实现

思考

public abstract class BeanUtils {
    private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
    private static final Set<Class<?>> unknownEditorTypes = Collections.newSetFromMap(new ConcurrentReferenceHashMap(64));
    private static final Map<Class<?>, Object> DEFAULT_TYPE_VALUES;

    public BeanUtils() {
    }

	......
	
	public static boolean isSimpleValueType(Class<?> type) {
        return Void.class != type && Void.TYPE != type && (ClassUtils.isPrimitiveOrWrapper(type) || Enum.class.isAssignableFrom(type) || CharSequence.class.isAssignableFrom(type) || Number.class.isAssignableFrom(type) || Date.class.isAssignableFrom(type) || Temporal.class.isAssignableFrom(type) || URI.class == type || URL.class == type || Locale.class == type || Class.class == type);
    }

    public static void copyProperties(Object source, Object target) throws BeansException {
        copyProperties(source, target, (Class)null, (String[])null);
    }

    public static void copyProperties(Object source, Object target, Class<?> editable) throws BeansException {
        copyProperties(source, target, editable, (String[])null);
    }

	......


}

BeanUtils 是一个抽象类,copyProperties是静态方法,那么可以通过继承该类,并扩展自己的静态方法实现功能封装。

ExtendBeanUtils 扩展类

package com.lfc.shop.common.core.util;

import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * 扩展BeanUtils
 *
 *      1. 拷贝列表元素的属性
 */
public class ExtendBeanUtils extends BeanUtils {

    /**
     * 简化版,无回调
     *
     * @param sources 待拷贝源列表
     * @param target 目标列表元素的类
     * @param <S> 数据源类
     * @param <T> 目标类
     * @return
     */
    public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) {
        return copyListProperties(sources, target, null);
    }

    /**
     *
     * @param sources 待拷贝源列表
     * @param target 目标列表元素的类
     * @param callback 回调函数
     * @param <S> 数据源类
     * @param <T> 目标类
     * @return
     */
    public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, ExtendBeanUtilsCallBack<S, T> callback) {
        List<T> targetList = new ArrayList<>(sources.size());

        if (!CollectionUtils.isEmpty(sources)) {
            sources.forEach(source -> {
                T t = target.get();
                copyProperties(source, t);

                if (Objects.nonNull(callback)) {
                    callback.callback(source, t);
                }

                targetList.add(t);
            });
        }

        return targetList;
    }

}

ExtendBeanUtilsCallback 回调接口

package com.lfc.shop.common.core.util;

@FunctionalInterface
public interface ExtendBeanUtilsCallback<S, T> {

    void callback(S s, T t);

}

使用

无回调

仅仅需要拷贝对象的值

List<User> userList = commonService.getUserMapper().selectBatchIds(uidList);
if (userList != null) {
    return ExtendBeanUtils.copyListProperties(userList, UserBaseVO::new);
}
return null;

有回调

回调函数,是在遍历赋值的过程中执行的,通常可以做一些数据判断再赋值的功能。这是我们项目中,清空身份证号的逻辑

List<User> userList = commonService.getUserMapper().selectBatchIds(uidList);

        if (userList != null) {
            return ExtendBeanUtils.copyListProperties(userList, UserBaseVO::new, (user, userBaseVO) -> {
                System.out.println("拷贝:" + user + ", 到:" + userBaseVO);
                if (StringUtils.isNoneBlank(user.getIdcard())) {
                    userBaseVO.setIdcard("");
                }
            });
        }
return null;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BeanUtils.copyProperties方法是Apache Commons BeanUtils库中的一个工具方法,用于将一个Java对象的属性拷贝到另一个Java对象中。它可以实现对象之间的属性值复制,无需手动逐个设置属性。 使用BeanUtils.copyProperties方法进行属性拷贝时,需要注意以下几点: 1. 属性名称和类型必须在源对象和目标对象中存在且匹配。 2. 属性值的拷贝是基于属性名称进行匹配的,而不是基于属性的位置。 3. 如果源对象和目标对象中存在相同名称但类型不匹配的属性,会抛出ConversionException异常。 4. 如果源对象中的属性值为null,则目标对象对应的属性值也会被设置为null。 5. 如果源对象和目标对象中存在嵌套对象,也会进行递归拷贝。 下面是一个示例代码,演示了如何使用BeanUtils.copyProperties方法进行属性拷贝: ```java import org.apache.commons.beanutils.BeanUtils; public class Main { public static void main(String[] args) { SourceObject source = new SourceObject(); source.setName("John"); source.setAge(25); TargetObject target = new TargetObject(); try { BeanUtils.copyProperties(target, source); System.out.println(target.getName()); // 输出:John System.out.println(target.getAge()); // 输出:25 } catch (Exception e) { e.printStackTrace(); } } } class SourceObject { private String name; private int age; // 省略getter和setter方法 } class TargetObject { private String name; private int age; // 省略getter和setter方法 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值