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