java基于BeanUtils拷贝非空属性工具类

本文介绍如何通过BeanNotNullUtil类实现SQL查询优化,避开空属性复制,针对集合操作提供copyListPropertiesIgnoreNull方法,有效提高多表关联查询性能并灵活组装数据。
摘要由CSDN通过智能技术生成

问题:

写SQL时难免会有一些需求要进行多张表关联才能查出来,但是进行多变查询的话,有又会造成查询效率严重下降,此时我们就需要拆分sql,拆分完可以显著提升查询效率,但此时我们每个sql查询的只是一部分数据,最后还需要将他们拼装到一起,传统的BeanUtil提供的copyProperties方法会将源数据的属性统统复制给目标对象这样不利于我们拼装sql,我们需要的只是非空的部分

思路:

copyProperties 方法的第三参数String... ignoreProperties(要忽略的属性),有了此种实现,我们就可以在数据拷贝之前拿到源数据的null值然后忽略就可以了详细请看getNullPropertyNames方法

有了这种还不算完,因为在拼装时还有很多情况查询的结果是一个集合,那么这种情况一般来说需要根据某一个字段来进行匹配,于是有了copyListPropertiesIgnoreNull方法,原理就是循环两个集合,首先循环source时通过反射获取到要匹配的字段,将其作为map的key,而这个对象就作为value,随后循环target利用反射获取到要匹配的字段从map中获取到前面放入的对象(map可以高效的索引到value),于是就可以利用前面封装好的copyPropertiesIgnoreNull方法拷贝非空的属性

/**
 * 属性复制(不复制空属性)
 *
 * @author zzt
 * @date 2022/08/20
 */
public class BeanNotNullUtil {

    /**
     * 获取到对象中属性为null的属性名
     *
     * @param source
     * @return
     */
    private static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (ObjectUtils.isEmpty(srcValue)) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 拷贝非空对象属性值
     *
     * @param source
     * @param target
     */
    public static void copyPropertiesIgnoreNull(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /**
     * 集合拷贝非空数据
     *
     * @param source       数据源
     * @param target       目标
     * @param propertyName 要匹配的属性名,例如两个集合使用id进行匹配拷贝 propertyName: "id"
     */
    public static void copyListPropertiesIgnoreNull(List<?> source, List<?> target, String propertyName) {
        if (CollectionUtils.isEmpty(source)) {
            throw new NullPointerException("copyListPropertiesIgnoreNull source源数据为空!");
        }
        Map<Object, Object> map = new HashMap<>(source.size());
        source.forEach(s -> {
            final BeanWrapper sourceBean = new BeanWrapperImpl(s);
            Object value = sourceBean.getPropertyValue(propertyName);
            if (value == null) {
                throw new NullPointerException("copyListPropertiesIgnoreNull获取参数异常");
            }
            map.put(value, s);
        });
        target.forEach(s -> {
            final BeanWrapper targetBean = new BeanWrapperImpl(s);
            Object value = targetBean.getPropertyValue(propertyName);
            if (value == null) {
                throw new NullPointerException("copyListPropertiesIgnoreNull获取参数异常");
            }
            Object o = map.get(value);
            copyPropertiesIgnoreNull(o, s);
        });
    }
}

测试:

public static void main(String[] args) {
        List<UserVo> vos1 = new ArrayList<>();
        vos1.add(new UserVo().setName("张三")
                .setId("1"));
        vos1.add(new UserVo().setId("2")
                .setName("李四"));

        List<UserVo> vos2 = new ArrayList<>();
        vos2.add(new UserVo().setId("1")
                .setPassword("123456"));
        vos2.add(new UserVo().setId("2")
                .setPassword("654321"));
        copyListPropertiesIgnoreNull(vos2, vos1,"id");
        System.out.println(vos1);
        //[UserVo(id=1, name=张三, password=123456), UserVo(id=2, name=李四, password=654321)]
    }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值