java 實現更新記錄時 詳細記錄各字段的具體更新細節日志


1、需求 

假如數據庫中有一條記錄從

{"id":1,"name":"張三","age":21,"sex":true}

更新成

{"id":1,"name":"李四","age":24,"sex":false}

則生成詳細的日志記錄

{

"id":1,"unityTag":"Person","unityOperate":"更新",

"unityMatter":"[姓名][年齡][性別]",

"unityContent":"[張三->李四][21->24][true->false]"

}

2、實現 

需要用到:反射 、注解

 

3、具體實現

/**
 * @author huangzhihua
 * @date 2020/11/9
 */
@Documented
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Description {

    public String name() default "";

    public boolean ignore() default false;

    public String dateFormat() default "";

}
/**
 * @author huangzhihua
 * @date 2020/11/9
 */
@Data
@Builder
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class UnityLog {

    /**
     * id
     */
    private Long id;

    /**
     * 數據庫表名
     */
    private String unityTag;

    /**
     * 數據庫表記錄id對應的操作日志
     */
    private Long unityTagId;

    /**
     * 操作人
     */
    private String unityOperator;

    /**
     * 操作時間
     */
    private Date unityOperateTime;

    /**
     * 操作類型
     */
    private String unityOperate;

    /**
     * 操作事項
     */
    private String unityMatter;

    /**
     * 操作內容
     */
    private String unityContent;
}
/**
 * @author huangzhihua
 * @date 2020/11/9
 */
public abstract class Base {
    public abstract Long getId();

    abstract EnumTableName getTableName();

    //region 生成數據修改日志
    public final static String ADD = "新增";
    public final static String UPDATE = "更新";
    public final static String DELETE = "刪除";


    public <T extends Base> UnityLog createLog(String unityOperate, T oldObj) throws IllegalAccessException {
        //保存操作日志
        UnityLog unityLog = comparatorObject(unityOperate, oldObj);
        unityLog.setId(getId());
        return unityLog;
    }

    /**
     * 比較新老對象的差別
     *
     * @param unityOperate
     * @param oldObj
     * @return
     * @throws IllegalAccessException
     */
    private UnityLog comparatorObject(String unityOperate, Object oldObj) throws IllegalAccessException {
        StringBuilder matter = new StringBuilder();
        StringBuilder content = new StringBuilder();

        if (oldObj != null && UPDATE.equals(unityOperate)) {
            Map<String, Object> oldMap = changeValueToMap(oldObj);
            Map<String, Object> newMap = changeValueToMap(this);
            if (oldMap != null && !oldMap.isEmpty()) {
                for (Map.Entry<String, Object> entry : oldMap.entrySet()) {
                    Object oldValue = entry.getValue();
                    Object newValue = newMap.get(entry.getKey());
                    if (!oldValue.equals(newValue)) {
                        matter.append("[").append(entry.getKey()).append("]");
                        content.append("[").append(oldValue).append("->").append(newValue).append("]");
                    }
                }
            }
        } else {
            matter.append("-");
            content.append("-");
        }
        return UnityLog.builder()
                .unityOperate(unityOperate)
                .unityTag(getTableName().getTableName())
                .unityMatter(String.valueOf(matter))
                .unityContent(String.valueOf(content))
                .build();
    }

    /**
     * 將類對象轉換成Map
     *
     * @param entity 原對象
     * @return Map
     * @throws IllegalAccessException 類型轉換時報錯
     */
    private static Map<String, Object> changeValueToMap(Object entity) throws IllegalAccessException {
        Map<String, Object> resultMap = new HashMap<>();
        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            if (PropertyUtils.isReadable(entity, name) && PropertyUtils.isWriteable(entity, name)) {
                if (field.isAnnotationPresent(Description.class)) {
                    Description anno = field.getAnnotation(Description.class);
                    //獲取private對象字段值
                    field.setAccessible(true);
                    resultMap.put(anno.name(), field.get(entity));
                }
            }
        }
        return resultMap;
    }
}
/**
 * @author huangzhihua
 * @date 2020/11/7
 */
@Data
@Builder
public class User extends Base {

    @Description(name = "id", ignore = true)
    public Long id;

    @Description(name = "姓名")
    private String name;

    @Description(name = "年齡")
    private Integer age;

    @Description(name = "描述")
    private String desc;

    @Override
    EnumTableName getTableName() {
        return EnumTableName.User;
    }
}
/**
 * @author huangzhihua
 * @date 2020/11/9
 */
public enum EnumTableName {
    User("user");

    EnumTableName(String tableName) {
        this.tableName = tableName;
    }

    private String tableName;

    public String getTableName() {
        return tableName;
    }
}
@Test
    void test() {
        User user1 = User.builder().id(1L).name("jack").age(19).desc("my name").build();
        User user2 = User.builder().id(1L).name("rose").age(18).desc("my name").build();
        try {
            UnityLog log = user2.createLog(Base.UPDATE, user1);
            System.out.println("log = " + log);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM