需求
1.为了记录一张表的操作日志,就是记录管理员进行了什么操作,需要记录下这个操作,并且要记录修改前 和 修改后的信息。
实现
1.下面是一段java 代码的实现。
package com.xescm.epc.utils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 比较同一类 的 两个实列 哪些属性存在差异
* 用于数据更新前后 对比。
*
* @author huxingnan
* @date 2018/3/29 18:55
*/
public class FieldComparetor {
public static List<CompareResult> compareFields(Object oldObj, Object newObj, String... ignoreFieldNames) {
try {
List<String> ignoreFieldNameList = Lists.newArrayList();
if (ignoreFieldNames != null) {
ignoreFieldNameList = Arrays.asList(ignoreFieldNames);
}
List<CompareResult> compareResults = Lists.newArrayList();
Class clazz;
if(oldObj.getClass() == Object.class || newObj.getClass() ==Object.class){
//如果是 Object 类型 不必对
return compareResults;
}
if (oldObj.getClass() == newObj.getClass()) {
// 属于同一种 类型
clazz = oldObj.getClass();
} else if (oldObj.getClass().isAssignableFrom(newObj.getClass())) {
//newObj 是 oldObj 的子类
clazz = oldObj.getClass();
} else if (newObj.getClass().isAssignableFrom(oldObj.getClass())) {
//oldObj 是 newObj 的子类
clazz = newObj.getClass();
} else {
//没必要对比了
return compareResults;
}
// 获取object的属性描述
PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
Object.class).getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
String name = pd.getName();// 属性名
//
if (ignoreFieldNameList.contains(name)) {
continue;
}
Method readMethod = pd.getReadMethod();// get方法
// 在oldObj上调用get方法等同于获得oldObj的属性值
Object oldValue = readMethod.invoke(oldObj);
// 在newObj调用get方法等同于获得newObj的属性值
Object newValue = readMethod.invoke(newObj);
if (oldValue == null && newValue == null) {
continue;
}
if (oldValue == null) {
compareResults.add(new CompareResult(null, newValue.toString(), name));
continue;
}
if (newValue == null) {
compareResults.add(new CompareResult(oldValue.toString(), null, name));
continue;
}
if (!oldValue.equals(newValue)) {// 比较这两个值是否相等,不等就可以放入list了
compareResults.add(new CompareResult(oldValue.toString(), newValue.toString(), name));
}
}
return compareResults;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* descripion: 校验两对象差异
* author: zhixing.wang
* date: 2018/3/30 11:21
* param: [requestBean, fitBean]
* return: java.lang.String
*/
public static String compareBean(Object requestBean, Object fitBean) {
StringBuilder stringBuilder = new StringBuilder();
try {
// 请求对象的Field
Class requestClazz = requestBean.getClass();
Field[] requestFields = requestClazz.getDeclaredFields();
// 本地对象的Field
Class fitClazz = fitBean.getClass();
Field[] fitFields = fitClazz.getDeclaredFields();
Map map = Maps.newHashMap();
for (Field field : fitFields) {
map.put(field.getName(), field.getName());
}
// serialVersionUID 不做比较
for (Field field : requestFields) {
if ("serialVersionUID".equals(field.getName())) {
continue;
}
// 请求对象有Field 但 本地对象没有的Field 不做比较
if (!map.containsKey(field.getName())) {
continue;
}
PropertyDescriptor requestPd = new PropertyDescriptor(field.getName(), requestClazz);
PropertyDescriptor fitPd = new PropertyDescriptor(field.getName(), fitClazz);
// 获取Field的get方法
Method getRequestMethod = requestPd.getReadMethod();
Method getFitMethod = fitPd.getReadMethod();
// 获取Field属性值
Object requestField = getRequestMethod.invoke(requestBean);
Object fitField = getFitMethod.invoke(fitBean);
// 返回异常信息
if (!Objects.equals(requestField, fitField)) {
stringBuilder.append(field.getName()).append("不正确;");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
/**
* 比较结果
*/
@Data
@AllArgsConstructor
public static class CompareResult {
private String oldValue;
private String newValue;
private String fieldName;
}
}
网友评论