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();
        }

    }

 



posted @ 2020-11-09 12:24  edda_huang  阅读(1721)  评论(0编辑  收藏  举报