zoukankan      html  css  js  c++  java
  • 学会使用BeanUtils,提高你的开发效率

    一、关于BeanUtils

    一说到BeanUtils,大家可能不清楚指的哪个BeanUtils。因为它在很多包里面都有,其中挺常用的就是

    (1)org.apache.commons.beanutils.BeanUtils

    (2)org.springframework.beans.BeanUtils

    这两者有什么区别呢?

    (1)类的性质不同

    apache:

    springframework:

    apache的是普通类,springframework的是抽象类。

    (2)部分相同方法使用方式不同

    名字相同,方法名称相同,参数类型和个数都相同,需要实现的功能也一样,但结果大相径庭。

    举例:copyProperties (用来在对象之间复制属性值)

    apache:

    springframework:

    眼尖的伙伴已经注意到了,apache的第一个参数是目标对象,第二个是源对象;springframework的第一个参数是源对象,第二个是目标对象。所以大家在开发的时候一定要注意引用的是哪个包。

    二、根据已有方法扩展

    因为开发的时候有很多类的属性都要重设值,很多时候大把的get、set方法占用你的篇幅与时间,导致拉低开发效率。

    所以在此扩展了一些经常用到的方法,供大家参考。

    1. 使用org.apache.commons.beanutils.BeanUtils.populate方法

    意为将Map中的数据封装到实体类。

    扩展之后可以将Map中的数据封装到实体类,并支持日期格式的转换。

      /**
         * 以Map的key和实体的字段名称为对应,复制Map中的值到实体中
         * 
         * @param target 目标对象
         * @param params Map
         * @return T
         */
        public static <T> T copyFields(T target, Map<String, Object> params) {
            if(null == params || params.isEmpty()) {
                return target;
            }
            try {
                org.apache.commons.beanutils.BeanUtils.populate(target, params);
            } catch (IllegalAccessException | InvocationTargetException e) {
                LOGGER.error(e.getMessage(), e);
            }
            return target;
        }

     注意:遇到日期类型不能转换,所以需要自己手动注册一个时间转换器。

    这里是在静态代码块里面注册的,将格式为yyyy-MM-dd的字符串转换成Date类型。

    static {
            // 注册BeanUtils转换器
            ConvertUtils.register(new Converter() {
    
                @SuppressWarnings("rawtypes")
                public Object convert(Class type, Object value) {
    
                    try {
                        return DateUtils.parseDate(String.valueOf(value), "yyyy-MM-dd");
                    } catch (ParseException e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                    return null;
                }
            }, Date.class);
        }

     2、使用org.springframework.beans.BeanUtils.getPropertyDescriptors方法

    意为获取类的属性描述器

    扩展之后可以从一个实体中复制非空字段的值到另一个实体中。

    /**
         * 以字段名称为关系,从一个实体中复制非空字段的值到另一个实体中
         * 
         * @param target 目标实体
         * @param source 源实体
         * @return T
         */
        public static <T, S> T copyNotNullFields(T target, S source) {
            Map<String, Object> params = getFiledValues(source, o -> (o != null));
            T newTarget = copyFields(target, params);
            return newTarget;
        }

    这里可以根据对属性值的判断,将符合条件的属性与其值封装成Map。 

    /**
         * 读取实体,以实体字段名为key,值为value,并将满足条件的value封装成一个Map
         * 
         * @param obj 源实体
         * @param predicate 条件
         * @return Map<String, Object>
         */
        public static Map<String, Object> getFiledValues(Object obj, Predicate<Object> predicate) {
            if(null == obj) {
                return Collections.emptyMap();
            }
            Map<String, Object> map = Maps.newHashMap();
            Arrays.asList(org.springframework.beans.BeanUtils.getPropertyDescriptors(obj.getClass())
            .stream()
            .filter(o -> !o.getName().equals("class"))
            .forEach(o -> 
            {
                String propertyName = o.getName();
                Method readMethod = o.getReadMethod();
                try {
                    Object propertyValue = readMethod.invoke(obj);
                    if(predicate.test(propertyValue)) {
                        map.put(propertyName, propertyValue);
                    }
                } catch (IllegalAccessException | IllegalArgumentException |         InvocationTargetException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            });
            return map;
        } 

     三、心得

    在开发时,如果经常在一些重复性的,且不必要的地方浪费时间时,那就要想一下方法来避免了,因为这会拉低你的开发效率。

    首先自己要思考,怎样才能去很好的解决。如果不能解决,那可以参考已有的解决方案(面向各大搜索引擎编程),学习他们解决问题的思路,看自己能不能活学活用。

    然后可以对已有的轮子进行一些自己的优化与封装,使得更加的符合自己的业务场景。

  • 相关阅读:
    bzoj2733 永无乡 平衡树按秩合并
    bzoj2752 高速公路 线段树
    bzoj1052 覆盖问题 二分答案 dfs
    bzoj1584 打扫卫生 dp
    bzoj1854 游戏 二分图
    bzoj3316 JC loves Mkk 二分答案 单调队列
    bzoj3643 Phi的反函数 数学 搜索
    有一种恐怖,叫大爆搜
    BZOJ3566 概率充电器 概率dp
    一些奇奇怪怪的过题思路
  • 原文地址:https://www.cnblogs.com/yl-space/p/13264829.html
Copyright © 2011-2022 走看看