java 實現更新記錄時 詳細記錄各欄位的具體更新細節日誌
阿新 • • 發佈:2018-12-18
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、具體實現
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * @author printsky * @since 2018/8/29 */ @Retention(RetentionPolicy.RUNTIME) public @interface LogCompar { /** * 中文名稱 * * @return String */ String name(); /** * Date 如何格式化,預設為空 * * @return String */ String dateFormat() default ""; }
/** * @author printsky * @since 2018/8/30 */ public enum EnumTableName { Person("Person"), Province("Province"), Income("Income"); EnumTableName(String tableName) { this.tableName = tableName; } private String tableName; public String getTableName() { return tableName; } }
/** * @author printsky * @since 2018/08/28 */ @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; public UnityLog(Long id, String unityTag, Long unityTagId, String unityOperator, Date unityOperateTime, String unityOperate, String unityMatter, String unityContent) { this.id = id; this.unityTag = unityTag; this.unityTagId = unityTagId; this.unityOperator = unityOperator; this.unityOperateTime = unityOperateTime; this.unityOperate = unityOperate; this.unityMatter = unityMatter; this.unityContent = unityContent; } public UnityLog(UnityLogBuilder builder) { this.unityTag = builder.unityTag; this.unityTagId = builder.unityTagId; this.unityOperator = builder.unityOperator; this.unityOperate = builder.unityOperate; this.unityMatter = builder.unityMatter; this.unityContent = builder.unityContent; } public UnityLog() { super(); } /** * id * * @return id id */ public Long getId() { return id; } /** * id * * @param id id */ public void setId(Long id) { this.id = id; } /** * 資料庫表名 * * @return unity_tag 資料庫表名 */ public String getUnityTag() { return unityTag; } /** * 資料庫表名 * * @param unityTag 資料庫表名 */ public void setUnityTag(String unityTag) { this.unityTag = unityTag == null ? null : unityTag.trim(); } /** * 資料庫表記錄id對應的操作日誌 * * @return unity_tag_id 資料庫表記錄id對應的操作日誌 */ public Long getUnityTagId() { return unityTagId; } /** * 資料庫表記錄id對應的操作日誌 * * @param unityTagId 資料庫表記錄id對應的操作日誌 */ public void setUnityTagId(Long unityTagId) { this.unityTagId = unityTagId; } /** * 操作人 * * @return unity_operator 操作人 */ public String getUnityOperator() { return unityOperator; } /** * 操作人 * * @param unityOperator 操作人 */ public void setUnityOperator(String unityOperator) { this.unityOperator = unityOperator == null ? null : unityOperator.trim(); } /** * 操作時間 * * @return unity_operate_time 操作時間 */ public Date getUnityOperateTime() { return unityOperateTime; } /** * 操作時間 * * @param unityOperateTime 操作時間 */ public void setUnityOperateTime(Date unityOperateTime) { this.unityOperateTime = unityOperateTime; } /** * 操作型別 * * @return unity_operate 操作型別 */ public String getUnityOperate() { return unityOperate; } /** * 操作型別 * * @param unityOperate 操作型別 */ public void setUnityOperate(String unityOperate) { this.unityOperate = unityOperate == null ? null : unityOperate.trim(); } /** * 操作事項 * * @return unity_matter 操作事項 */ public String getUnityMatter() { return unityMatter; } /** * 操作事項 * * @param unityMatter 操作事項 */ public void setUnityMatter(String unityMatter) { this.unityMatter = unityMatter == null ? null : unityMatter.trim(); } /** * 操作內容 * * @return unity_content 操作內容 */ public String getUnityContent() { return unityContent; } /** * 操作內容 * * @param unityContent 操作內容 */ public void setUnityContent(String unityContent) { this.unityContent = unityContent == null ? null : unityContent.trim(); } public void setIdAndOperator(Long unityTagId, String unityOperator) { this.unityTagId = unityTagId; this.unityOperator = unityOperator; } public static UnityLogBuilder builder() { return new UnityLogBuilder(); } public static class UnityLogBuilder { private String unityTag; private Long unityTagId; private String unityOperator; private String unityOperate; private String unityMatter; private String unityContent; public UnityLogBuilder unityTag(String unityTag) { this.unityTag = unityTag; return this; } public UnityLogBuilder unityTagId(Long unityTagId) { this.unityTagId = unityTagId; return this; } public UnityLogBuilder unityOperator(String unityOperator) { this.unityOperator = unityOperator; return this; } public UnityLogBuilder unityOperate(String unityOperate) { this.unityOperate = unityOperate; return this; } public UnityLogBuilder unityMatter(String unityMatter) { this.unityMatter = unityMatter; return this; } public UnityLogBuilder unityContent(String unityContent) { this.unityContent = unityContent; return this; } public UnityLog build() { return new UnityLog(this); } } }
/**
* @author printsky
* @since 2018/8/30
*/
public class Person extends Base {
@LogCompar(name = "id")
private Long id;
@LogCompar(name = "姓名")
private String name;
@LogCompar(name = "年齡")
private Integer age;
@LogCompar(name = "性別")
private boolean sex;
public Person() {
}
public Person(Long id, String name, Integer age, boolean sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Override
EnumTableName getTableName() {
return EnumTableName.Person;
}
}
這個類是主要的的邏輯實現部分
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author printsky
* @since 2018/8/30
*/
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(LogCompar.class)) {
LogCompar anno = field.getAnnotation(LogCompar.class);
//獲取private物件欄位值
field.setAccessible(true);
resultMap.put(anno.name(), field.get(entity));
}
}
}
return resultMap;
}
//endregion
}
public static void main(String[] args) {
Gson gson=new Gson();
Person user1=new Person(1L,"張三",21,true);
System.out.println("user1 = " + gson.toJson(user1));
Person user2=new Person(1L,"李四",24,false);
System.out.println("user2 = " + gson.toJson(user2));
try {
UnityLog log = user2.createLog(Base.UPDATE, user1);
System.out.println("log = " + gson.toJson(log));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}