用户在前端修改的字段记录,数据变更记录日志

开发中经常遇到业务提出一些日志变更记录,例如用户修改了哪些字段,又或者B系统调用我方修改了表的哪些字段,为了节省时间省略 is else判断,大概写个对象变更工具类。

本文介绍了一个对象变更对比工具类的实现方案,主要用于记录业务数据变更日志。核心功能包括:
1)通过自定义@FieldName注解为字段添加中文描述;
2)利用反射机制比较两个对象字段差异;
3)输出带中文注释的变更记录。该工具类可自动识别被@FieldName注解标记的字段,返回字段名、中文描述及变更前后的值,适用于系统间接口调用或用户操作日志等场景。示例展示了如何定义实体类、使用注解及调用比较方法,最终输出易读的变更记录。该方案简化了日志开发工作,提高了可维护性。

1、自定义@FieldName注解(通过注解获取中文注释)


import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {
    String value(); // 字段的中文描述
}

2、创建一个 对象对比工具类

import java.lang.reflect.Field;
import java.util.*;

public class ObjectCompareUtil {

    /**
     * 比较两个对象的字段差异,并返回带中文注释的变更记录
     */
    public static List<FieldChange> compareFieldsWithChinese(Object oldObj, Object newObj) {
        List<FieldChange> changes = new ArrayList<>();

        if (oldObj == null || newObj == null || !oldObj.getClass().equals(newObj.getClass())) {
            return changes;
        }

        Field[] fields = oldObj.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object oldValue = field.get(oldObj);
                Object newValue = field.get(newObj);

                if (isFieldChanged(oldValue, newValue)) {
                    String chineseName = getFieldChineseName(field);
                    changes.add(new FieldChange(
                            field.getName(),
                            chineseName,  // 添加中文注释
                            oldValue,
                            newValue
                    ));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return changes;
    }

    /**
     * 获取字段的中文注释(通过 @FieldName 注解)
     */
    private static String getFieldChineseName(Field field) {
        FieldName annotation = field.getAnnotation(FieldName.class);
        return annotation != null ? annotation.value() : field.getName();
    }

    /**
     * 判断字段值是否发生变化
     */
    private static boolean isFieldChanged(Object oldValue, Object newValue) {
        return (oldValue == null && newValue != null) ||
                (oldValue != null && !oldValue.equals(newValue));
    }

    /**
     * 字段变更记录类(增强版)
     */
    public static class FieldChange {
        private String fieldName;      // 字段英文名
        private String fieldChinese;  // 字段中文名
        private Object oldValue;
        private Object newValue;

        public FieldChange(String fieldName, String fieldChinese, Object oldValue, Object newValue) {
            this.fieldName = fieldName;
            this.fieldChinese = fieldChinese;
            this.oldValue = oldValue;
            this.newValue = newValue;
        }

        // Getters
        public String getFieldName() { return fieldName; }
        public String getFieldChinese() { return fieldChinese; }
        public Object getOldValue() { return oldValue; }
        public Object getNewValue() { return newValue; }

        @Override
        public String toString() {
            return String.format(
                    "字段【%s】从 '%s' 修改为 '%s'",
                    fieldChinese, oldValue, newValue
            );
        }
    }
}

3、在对象上使用注解


import cn.com.xxx.common.core.web.domain.BaseEntity;
import cn.com.xxx.common.security.utils.FieldName;
import lombok.Data;

/**
 * 产品版本信息
 */
@Data
public class ProdVersion {
    /**
     * 版本状态 
     */
   private String status;

   /**
    * 是否删除:0未删除 1已删除
    */
   @FieldName("是否删除")
   private String isDel;
}

4、使用方法参考

public static void main(String[] args) {
        ProdVersion oldPo = new ProdVersion();
        oldPo.setStatus("0");
        oldPo.setIsDel("N");
        ProdVersion newPo = new ProdVersion();
        newPo.setStatus("1");
        newPo.setIsDel("NYY");
        List<ObjectCompareUtil.FieldChange> fieldChanges = ObjectCompareUtil.compareFieldsWithChinese(oldPo, newPo);
        System.out.println(fieldChanges.toString());
    }

运行输出结果:[字段【status】从 '0' 修改为 '1', 字段【是否删除】从 'N' 修改为 'Y']

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值