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

image

今日一问

一个打工的,到底需要多少台电脑?
欢迎在下方评论留言

黑壳博客

正文

最近项目有个小需求,业务数据修改后要记录个日志,要记录变动的前后的值。

需要给Bean的属性添加属性值 用于日志参数备注 例如 参数userName 在日志中记录为 用户名称

日志示例

 某某某功能 产生变动日志内容  变动前 用户名称:李三  变动后 用户名称:李四

查了一下,自己以前也没整理过类似的记录文章,这次顺便记录一下,方便新人程序员参考。

本篇先出干货,给参数添加注解记录中文备注。数据变动对比,会在下篇文章。

方式用Java Bean的遍历,利用Java的反射原理。Bean的属性添加属性值,使用Java的自定义注解。

例子:

首先创建注解类:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SetFieldAttribute {
    String fieldName() default "";
    String fieldType() default "";
}

创建Java Bean:

    import java.util.List;
    
    public class UserBean {
        private static final long i = 1l;
    
        @SetFieldAttribute(fieldName="userId")
        private String id;
    
        @SetFieldAttribute(fieldName="userName")
        private String name;
    
        @SetFieldAttribute(fieldName="userAge")
        private String age;
    
        @SetFieldAttribute(fieldName="userEmail")
        private String email;
    
        @SetFieldAttribute(fieldName="userFavourite", fieldType="list")
        private List<String> favourite;
    
        /**
         * @return the id
         */
        @SetFieldAttribute(fieldName="userGetId")
        public String getId() {
            return id;
        }
    
        /**
         * @param id the id to set
         */
        public void setId(String id) {
            this.id = id;
        }
    
        /**
         * @return the name
         */
        @SetFieldAttribute(fieldName="userGetName")
        public String getName() {
            return name;
        }
    
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
    
        /**
         * @return the age
         */
        @SetFieldAttribute(fieldName="userGetAge")
        public String getAge() {
            return age;
        }
    
        /**
         * @param age the age to set
         */
        public void setAge(String age) {
            this.age = age;
        }
    
        /**
         * @return the email
         */
        @SetFieldAttribute(fieldName="userGetEmail")
        public String getEmail() {
            return email;
        }
    
        /**
         * @param email the email to set
         */
        public void setEmail(String email) {
            this.email = email;
        }
    
        /**
         * @return the favourite
         */
        @SetFieldAttribute(fieldName="userGetFavourite", fieldType="list")
        public List<String> getFavourite() {
            return favourite;
        }
    
        /**
         * @param favourite the favourite to set
         */
        public void setFavourite(List<String> favourite) {
            this.favourite = favourite;
        }
    }

遍历Bean 工具参考类:

 
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by kzyuan on 2019-09-05 11:28
 */
public class BeanUtil {
    private static UserBean userBean;

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 创建User Bean对象,并设值
        setUserBean();
        //遍历 Bean
        traversalBean();
        // 通过Bean的方法遍历 
        traversalFunction();
    }

    // 创建User Bean对象,并设值
    private static void setUserBean() {
        userBean = new UserBean();
        userBean.setId("1");
        userBean.setName("壳叔");
        userBean.setAge("35");
        userBean.setEmail("keshu@bhusk.com");
        List<String> favouriteList = new ArrayList<String>();
        favouriteList.add("蹦极");
        favouriteList.add("高空跳伞");
        favouriteList.add("滑雪");
        favouriteList.add("旅游");
        userBean.setFavourite(favouriteList);
    }

    // 遍历 Bean
    private static void traversalBean() throws Exception {

        // 通过Bean的属性遍历
        System.out.println("通过Bean的属性遍历");

        Field[] fields = userBean.getClass().getDeclaredFields();
        for (Field field : fields) {
            String mod = Modifier.toString(field.getModifiers());
            System.out.println("mod = " + mod);
            // 跳过静态属性
            if (mod.indexOf("static") != -1) {
                continue;
            }

            // 取得注解的设置的属性值
            SetFieldAttribute setField = field.getAnnotation(SetFieldAttribute.class);
            if (setField != null) {
                String fieldName = setField.fieldName();
                String fieldType = 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);

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

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


    }
    private static void traversalFunction() throws Exception {
        System.out.println("通过Bean的方法遍历");

        // 通过Bean的方法遍历
        Method[] methods = userBean.getClass().getDeclaredMethods();
        for (Method method : methods) {
            // 取得注解的设置的属性值
            SetFieldAttribute setField = method.getAnnotation(SetFieldAttribute.class);
            if (setField != null) {
                String fieldName = setField.fieldName();
                String fieldType = setField.fieldType();

                System.out.println("注解的属性 fieldName = " + fieldName);
                System.out.println("注解的属性 fieldType = " + fieldType);
                Class[] methodParam = null;
                Object[] params = {};
                Object retVal = null;
                if (method.getName().substring(0, 3).equals("get")) {
                    String mod = Modifier.toString(method.getModifiers());
                    System.out.println("mod = " + mod);
                    System.out.println("User Bean 属性的Get方法名 getMethod = " + method.getName());

                    retVal = userBean.getClass().getMethod(method.getName(), methodParam).invoke(userBean, params);

                    if (fieldType.equals("list")) {
                        List<String> favouriteList = (List<String>) retVal;
                        int i = 1;
                        for (String favourite : favouriteList) {
                            System.out.println("User Bean 属性的值 " + method.getName() + " : " + i + " = " + favourite);
                            I++;
                        }
                    } else {
                        // 取得Bean属性的值
                        System.out.println("User Bean 属性的值 " + method.getName() + " = " + retVal);
                    }
                }
            }
        }
    }
}

执行结果:

通过Bean的属性遍历
mod = private static final
mod = private
注解的属性 fieldName = userId
注解的属性 fieldType = 
User Bean 属性的Get方法名 getMethod = getId
User Bean 属性的值 id = 1
mod = private
注解的属性 fieldName = userName
注解的属性 fieldType = 
User Bean 属性的Get方法名 getMethod = getName
User Bean 属性的值 name = 壳叔
mod = private
注解的属性 fieldName = userAge
注解的属性 fieldType = 
User Bean 属性的Get方法名 getMethod = getAge
User Bean 属性的值 age = 35
mod = private
注解的属性 fieldName = userEmail
注解的属性 fieldType = 
User Bean 属性的Get方法名 getMethod = getEmail
User Bean 属性的值 email = keshu@bhusk.com
mod = private
注解的属性 fieldName = userFavourite
注解的属性 fieldType = list
User Bean 属性的Get方法名 getMethod = getFavourite
User Bean 属性的值 favourite : 1 = 蹦极
User Bean 属性的值 favourite : 2 = 高空跳伞
User Bean 属性的值 favourite : 3 = 滑雪
User Bean 属性的值 favourite : 4 = 旅游

通过Bean的方法遍历
注解的属性 fieldName = userGetName
注解的属性 fieldType = 
mod = public
User Bean 属性的Get方法名 getMethod = getName
User Bean 属性的值 getName = 壳叔
注解的属性 fieldName = userGetId
注解的属性 fieldType = 
mod = public
User Bean 属性的Get方法名 getMethod = getId
User Bean 属性的值 getId = 1
注解的属性 fieldName = userGetAge
注解的属性 fieldType = 
mod = public
User Bean 属性的Get方法名 getMethod = getAge
User Bean 属性的值 getAge = 35
注解的属性 fieldName = userGetEmail
注解的属性 fieldType = 
mod = public
User Bean 属性的Get方法名 getMethod = getEmail
User Bean 属性的值 getEmail = keshu@bhusk.com
注解的属性 fieldName = userGetFavourite
注解的属性 fieldType = list
mod = public
User Bean 属性的Get方法名 getMethod = getFavourite
User Bean 属性的值 getFavourite : 1 = 蹦极
User Bean 属性的值 getFavourite : 2 = 高空跳伞
User Bean 属性的值 getFavourite : 3 = 滑雪
User Bean 属性的值 getFavourite : 4 = 旅游
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,504评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,898评论 1 300
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,218评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,322评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,693评论 3 290
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,812评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,747评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,476评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,700评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,190评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,541评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,206评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,129评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,903评论 0 199
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,894评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,748评论 2 274

推荐阅读更多精彩内容