美文网首页JAVA工具类
一款对象差异比较工具方法

一款对象差异比较工具方法

作者: 白袜子先生 | 来源:发表于2018-04-12 17:12 被阅读57次

    需求

    1.为了记录一张表的操作日志,就是记录管理员进行了什么操作,需要记录下这个操作,并且要记录修改前 和 修改后的信息。

    实现

    1.下面是一段java 代码的实现。

    package com.xescm.epc.utils;
    
    import com.google.common.collect.Lists;
    import com.google.common.collect.Maps;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    
    /**
     * 比较同一类 的 两个实列 哪些属性存在差异
     * 用于数据更新前后 对比。
     *
     * @author huxingnan
     * @date 2018/3/29 18:55
     */
    public class FieldComparetor {
    
    
        public static List<CompareResult> compareFields(Object oldObj, Object newObj, String... ignoreFieldNames) {
            try {
                List<String> ignoreFieldNameList = Lists.newArrayList();
                if (ignoreFieldNames != null) {
                    ignoreFieldNameList = Arrays.asList(ignoreFieldNames);
                }
                List<CompareResult> compareResults = Lists.newArrayList();
    
                Class clazz;
    
                if(oldObj.getClass() == Object.class || newObj.getClass() ==Object.class){
                    //如果是 Object 类型 不必对
                    return compareResults;
                }
                if (oldObj.getClass() == newObj.getClass()) {
                    // 属于同一种 类型
                    clazz = oldObj.getClass();
                } else if (oldObj.getClass().isAssignableFrom(newObj.getClass())) {
                    //newObj  是 oldObj 的子类
                    clazz = oldObj.getClass();
                } else if (newObj.getClass().isAssignableFrom(oldObj.getClass())) {
                    //oldObj 是 newObj 的子类
                    clazz = newObj.getClass();
                } else {
                    //没必要对比了
                    return compareResults;
                }
    
    
                // 获取object的属性描述
                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                        Object.class).getPropertyDescriptors();
                for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
                    String name = pd.getName();// 属性名
    //
                    if (ignoreFieldNameList.contains(name)) {
                        continue;
                    }
                    Method readMethod = pd.getReadMethod();// get方法
                    // 在oldObj上调用get方法等同于获得oldObj的属性值
                    Object oldValue = readMethod.invoke(oldObj);
                    // 在newObj调用get方法等同于获得newObj的属性值
                    Object newValue = readMethod.invoke(newObj);
    
                    if (oldValue == null && newValue == null) {
                        continue;
                    }
                    if (oldValue == null) {
                        compareResults.add(new CompareResult(null, newValue.toString(), name));
                        continue;
                    }
                    if (newValue == null) {
                        compareResults.add(new CompareResult(oldValue.toString(), null, name));
                        continue;
                    }
                    if (!oldValue.equals(newValue)) {// 比较这两个值是否相等,不等就可以放入list了
                        compareResults.add(new CompareResult(oldValue.toString(), newValue.toString(), name));
                    }
                }
                return compareResults;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * descripion: 校验两对象差异
         * author: zhixing.wang
         * date: 2018/3/30 11:21
         * param: [requestBean, fitBean]
         * return: java.lang.String
         */
        public static String compareBean(Object requestBean, Object fitBean) {
            StringBuilder stringBuilder = new StringBuilder();
            try {
                // 请求对象的Field
                Class requestClazz = requestBean.getClass();
                Field[] requestFields = requestClazz.getDeclaredFields();
                // 本地对象的Field
                Class fitClazz = fitBean.getClass();
                Field[] fitFields = fitClazz.getDeclaredFields();
    
                Map map = Maps.newHashMap();
                for (Field field : fitFields) {
                    map.put(field.getName(), field.getName());
                }
                // serialVersionUID 不做比较
                for (Field field : requestFields) {
                    if ("serialVersionUID".equals(field.getName())) {
                        continue;
                    }
                    // 请求对象有Field 但 本地对象没有的Field 不做比较
                    if (!map.containsKey(field.getName())) {
                        continue;
                    }
                    PropertyDescriptor requestPd = new PropertyDescriptor(field.getName(), requestClazz);
                    PropertyDescriptor fitPd = new PropertyDescriptor(field.getName(), fitClazz);
                    // 获取Field的get方法
                    Method getRequestMethod = requestPd.getReadMethod();
                    Method getFitMethod = fitPd.getReadMethod();
                    // 获取Field属性值
                    Object requestField = getRequestMethod.invoke(requestBean);
                    Object fitField = getFitMethod.invoke(fitBean);
                    // 返回异常信息
                    if (!Objects.equals(requestField, fitField)) {
                        stringBuilder.append(field.getName()).append("不正确;");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    
        /**
         * 比较结果
         */
        @Data
        @AllArgsConstructor
        public static class CompareResult {
            private String oldValue;
            private String newValue;
            private String fieldName;
        }
    }
    
    
    

    相关文章

      网友评论

        本文标题:一款对象差异比较工具方法

        本文链接:https://www.haomeiwen.com/subject/vmrfkftx.html