简介
遇到一个情况,在更新数据库的数据时,需要把每次变动的内容记录下来。
写了个比较通用的工具—只能比较基本类型和String。
实现
public class FieldCompareUtils {
/**
* 字段值变动比较工具
* @param source
* @param target
* @return map形式 key字段名,value list.get(0) 改变前的值 list.get(1) 改变后的值 异常返回空
*/
public static Map<String, List<Object>> fieldCompare(Object source, Object target) {
if (source == null || target == null || source.getClass() != target.getClass()){
return null;
}
try {
HashMap<String, List<Object>> resultMap = new HashMap<>();
// 获取 source 所有字段
List<Field> sourceFields = getAllFields(source);
// 字段map
Map<String, Field> sourceFieldsMap = sourceFields.stream().collect(
Collectors.toMap(Field::getName, field -> field));
// 获取target 所有字段
List<Field> targetFields = getAllFields(target);
// 循环比较
for (Field targetField : targetFields) {
String name = targetField.getName();
Field sourceField = sourceFieldsMap.get(name);
if (sourceField != null) {
Object sourceValue = sourceField.get(source);
Object targetValue = targetField.get(target);
// 字段值不同时记录下来
if (targetValue != null && !targetValue.equals(sourceValue)) {
List list = new ArrayList();
list.add(sourceValue);
list.add(targetValue);
resultMap.put(sourceField.getName(), list);
}
}
}
return resultMap;
}catch (IllegalAccessException e) {
}
return null;
}
/**
* 获取包括父类在内的所有字段
* @param source
* @return
*/
public static List<Field> getAllFields(Object source) {
List<Field> fieldList = new ArrayList<>();
Class clazz = source.getClass();
while (clazz != Object.class) {
Field[] declaredFields = clazz.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
declaredFields[i].setAccessible(true);
fieldList.add(declaredFields[i]);
}
clazz = clazz.getSuperclass();
}
return fieldList;
}
public static void main(String[] args) {
Student source = new Student();
Student target = new Student();
source.name = "nihao";
target.name = "test";
target.age = 12;
Map<String, List<Object>> stringListMap = fieldCompare(source, target);
Gson gson = new Gson();
System.out.println(gson.toJson(stringListMap));
}
}
class Student{
String name;
Integer age;
}
运行结果
{"name":["nihao","test"],"age":[null,12]}