在公司項目中,經常會需要記錄資料實體的具體修改内容,即對比資料前後修改的變化日志,這裡我寫了一個工具類UpdateFieldLogUtils,用來記錄資料修改詳細日志。
該工具類傳入修改前、後的實體對象Object,傳回具體修改日志内容。
1、對于有父類的object,通過遞歸的形式利用函數getSuperclass擷取所有的字段,将所有字段field插入到清單fieldList,然後這個周遊所有的filed,對比實體字段是否修改。
2、通過ApiModelProperty注解定義字段轉義的業務中文名稱,利用f.getAnnotation擷取字段的ApiModelProperty注解,然後利用f.getAnnotation(ApiModelProperty.class);String filedName = f.getName();擷取字段注解中定義的名稱。
3、對于id、修改時間、狀态type/status等字段過濾
package com.demo.example.utils;
import io.swagger.annotations.ApiModelProperty;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UpdateFieldLogUtils {
public static String updateLogMessage(Object object, Object oldObject) throws Exception {
// 得到類和父類對象,得到屬性集合
List<Field> fieldList = new ArrayList<>();
Class stuCla = object.getClass();
while (stuCla != null) {//當父類為null的時候說明到達了最上層的父類(Object類).
fieldList.addAll(Arrays.asList(stuCla.getDeclaredFields()));
stuCla = stuCla.getSuperclass(); //得到父類,然後賦給自己
}
Boolean isUpdated = false;
//周遊屬性
StringBuilder afterValueBuilder = new StringBuilder();
StringBuilder beforeValueBuilder = new StringBuilder();
for (Field f : fieldList) {
// 設定屬性是可以通路的(私有的也可以)
f.setAccessible(true);
// 得到此屬性的值
Object val = f.get(object);
//隻要有屬性不為空
if (val == null
|| "updateTime".equals(f.getName())
|| "updateDate".equals(f.getName())
|| "updateUser".equals(f.getName())
|| "auditTime".equals(f.getName())
|| "auditorId".equals(f.getName())
|| "auditorName".equals(f.getName())
|| "modifyDate".equals(f.getName())
|| "receivedStatus".equals(f.getName())
|| "realAmount".equals(f.getName())
|| f.getName().contains("id")
|| f.getName().contains("Id")
|| f.getName().endsWith("status")
|| f.getName().endsWith("Type")) {
continue;
}
Object oldVal = f.get(oldObject);
ApiModelProperty apiModelProperty =
f.getAnnotation(ApiModelProperty.class);
String filedName = f.getName();
if(apiModelProperty != null){
filedName = apiModelProperty.value();
}
if (oldVal == null) {
afterValueBuilder.append(filedName + ":" + f.get(object) + " ");
beforeValueBuilder.append(filedName + ":" + f.get(oldObject) + " ");
isUpdated = true;
} else if (!f.get(object).toString().equals(f.get(oldObject).toString())) {
afterValueBuilder.append(filedName + ":" + f.get(object) + " ");
beforeValueBuilder.append(filedName + ":" + f.get(oldObject) + " ");
isUpdated = true;
continue;
}
}
if (!isUpdated) {
return null;
}
return beforeValueBuilder + "修改為 " + afterValueBuilder;
}
}