[下] 业务数据变动日志记录的一次需求

本文由黑壳博客原创

本文来源[下]业务数据变动日志记录的一次需求

今日一问

群友提问,怎么用 39.74 过半个月?

欢迎评论区回答,会在群内随机摘取问题or段子

渴望的目光

正文

紧接着上次的话题来聊[上]业务数据变动日志记录的一次需求

上次因为项目需求,要做一个记录日志的功能,其实功能还蛮简单的造一个小工具类就可以了。

这篇文章主要就是把上篇文章的代码改造成工具类,方便后期有相同需求的人,不用在手写了~

那我们开始直接进入话题

  1. 首先第一步给bean加载完我们自定义的注解以后,进行工具类调用,如果你不知道自定义注解,请阅读[上]业务数据变动日志记录的一次需求

  2. 工具类 BeanUtil

import	java.util.HashMap;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;

/**
 * 本工具类目的是针对两个Bean内容做比较
 * 效果是为了日志记录方便
 * 例如日志内容 "参数名:xxx, 变动前:xxx -> 变动后:xxx;......"
 *
 * Created by kzyuan on 2019-09-05 11:28
 */
public class BeanUtil {
    private static UserBean userBeanNew;
    private static UserBean userBeanOld;


    public static void main(String[] args)  {
        // 创建User Bean对象,并设值
        setUserBean();
        //数据对比返回结果集
        Map<String,String> resultMap = dataComparison(userBeanNew,userBeanOld);
    }

    // 创建User Bean对象,并设值
    private static void setUserBean() {
        userBeanOld = new UserBean();
        userBeanOld.setId("1");
        userBeanOld.setName("壳叔");
        userBeanOld.setAge("35");
        userBeanOld.setEmail("keshu@bhusk.com");

        userBeanNew = new UserBean();
        userBeanNew.setId("2");
        userBeanNew.setName("kk 壳");
        userBeanNew.setAge("36");
        userBeanNew.setEmail("kk@bhusk.com");
    }

    // 遍历 Bean
    private static Map<String,DataLogger> traversalBean(Object obj) throws Exception {

        //创建Map容器
        Map<String,DataLogger> objMap = new HashMap<String, DataLogger> ();

        //开始记录容器值
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            DataLogger dataLogger = new DataLogger();
            String mod = Modifier.toString(field.getModifiers());
            System.out.println("mod = " + mod);
            dataLogger.setMod(mod);
            // 跳过静态属性
            if (mod.indexOf("static") != -1) {
                continue;
            }

            // 取得注解的设置的属性值
            SetFieldAttribute setField = field.getAnnotation(SetFieldAttribute.class);
            if (setField != null) {
                String fieldName = setField.fieldName();
                String fieldType = setField.fieldType();
                dataLogger.setFieldName(setField.fieldName());
                dataLogger.setFieldType(setField.fieldType());

                System.out.println("注解的属性 fieldName = " + fieldName);
                System.out.println("注解的属性 fieldType = " + fieldType);

                String getMethod = "get" + field.getName().substring(0, 1).toUpperCase()
                        + field.getName().substring(1);
                System.out.println("User Bean 属性的Get方法名 getMethod = " + getMethod);
                dataLogger.setMethod(getMethod);


                Class[] methodParam = null;
                Object[] params = {};
                Object retVal = obj.getClass().getMethod(getMethod, methodParam).invoke(obj, params);

                if (fieldType.equals("list")) {
//                    List<String> list = (List<String>) retVal;
//                    if(null == list) {continue;}
//                    int i = 1;
//                    for (String favourite : list ) {
//                        System.out.println("User Bean 属性的值 " + field.getName() + " : " + i + " = " + favourite);
//                        i++;
//                    }
                } else {
                    // 取得Bean属性的值
                    System.out.println("User Bean 属性的值 " + field.getName() + " = " + retVal);
                    dataLogger.setFieldValue(retVal);
                }
            }
            objMap.put(field.getName(), dataLogger);
        }

        return objMap;
    }

   /**
     * 类数据对比方法 会返回一个map 会存储发生变动的日志
     * @param newObj 变动后的bean
     * @param oldObj 变动前的bean
     */
    private static Map<String,String> dataComparison(Object newObj,Object oldObj) {

        //结果容器
        Map<String,String> resultMap = new HashMap<String, String>();

        try {
            /**
             * 整理Bean分析数据
             */
            Map<String,DataLogger> newObjMap = BeanUtil.traversalBean(newObj);
            Map<String,DataLogger> oldObjMap = BeanUtil.traversalBean(oldObj);


            /**
             * 开始分析两组map数据
             */
            for (Map.Entry<String, DataLogger> entry : newObjMap.entrySet()) {

                /**
                 * 判断两组值数据
                 */
                if (entry.getValue().getFieldValue() != oldObjMap.get(entry.getKey()).getFieldValue()) {

                    /**
                     * 记录日志的结果
                     */
//                    resultMap.put(entry.getKey(), " field name: " + entry.getValue().getFieldName() +
//                            " , new field value: " + entry.getValue().getFieldValue() +
//                            " -> old field value: " + oldObjMap.get(entry.getKey()).getFieldValue());
                    resultMap.put(entry.getKey(), " 发生列名: " + entry.getValue().getFieldName() +
                            " , 变动后内容值: " + entry.getValue().getFieldValue() +
                            " -> 变动前内容值: " + oldObjMap.get(entry.getKey()).getFieldValue());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }
}


/**
 * 用于存储解析后的bean
 */
class DataLogger {
    private String mod;
    /**
     * 字段名
     */
    private String fieldName;

    /**
     * 字段内容
     */
    private Object fieldValue;

    /**
     * 字段类型
     */
    private String fieldType;

    /**
     * 属性的Get方法名
     */
    private String method;

    public String getMod() {
        return mod;
    }

    public void setMod(String mod) {
        this.mod = mod;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public Object getFieldValue() {
        return fieldValue;
    }

    public void setFieldValue(Object fieldValue) {
        this.fieldValue = fieldValue;
    }

    public String getFieldType() {
        return fieldType;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }


    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }
}
	
  1. 具体调用方式参考工具类的main方法~~~ 你会得到一个map结果集,最后根据自己需要自行处理优化结果集~~ 其它的我可不管咯

  2. 那本篇结束,我该去泡泡面了。

本篇提到的代码文件,已经均提交到Github

地址->https://dwz.cn/g9ZSYMFQ

About

欢迎在评论写下你的程序员趣事~~

欢迎加入我们的小组织 ,大家都叫壳叔,期待你的到来。

我们也会定期在群内聊天记录中抽取有趣的事情或者小问题。

欢迎关注公众号

黑壳博客微信公众号

这是我们的Group 不定期开放 但是有定期的红包

黑壳家根据地 Q群:200408242

黑壳博客 blog.bhusk.com

E-mail:keshu@bhusk.com

本文由 黑壳博客的壳叔 创作或转载,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。

可自由转载、引用,但需署名作者且注明文章

留下你的脚步
推荐阅读