前言
对比两次提交记录,判断用户是否有修改信息,如有修改将修改前后结果保存下来。
由于字段太多,使用大量if判断,工作量太大。
1.定义注解,使用该注解的属性,会被对比
代码如下(示例):
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ObjectCompare {
/**
* 属性描述
* @return
*/
String value();
}
2.对比工具方法
代码如下(示例):
/**
* 对比两个相同类型实体属性
*
* @param obj1 对象1
* @param obj2 对象2
* @param clazz 类
* @return List<ComparisonResult>
*/
public static List<ComparisonResult> compareFields(Object obj1, Object obj2, Class clazz) throws Exception {
try {
List<String> ignoreList = getCompareFields(clazz);
Map<String, String> descsMap = getFieldSwaggerValue(clazz);
List<ComparisonResult> list = new ArrayList<>();
// 两个对象是否同一类型
if (obj1.getClass() == obj2.getClass()) {
Class<?> claz = obj1.getClass();
// 获取属性描述
PropertyDescriptor[] pds = Introspector.getBeanInfo(claz, Object.class).getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
String name = pd.getName().substring(0, 1).toLowerCase() + pd.getName().substring(1);
String label = descsMap.get(name);
if (!ignoreList.contains(name)) {
continue;
}
Method readMethod = pd.getReadMethod();
Object o1 = readMethod.invoke(obj1);
Object o2 = readMethod.invoke(obj2);
String r1 = null, r2 = null;
if (Objects.isNull(o1) && Objects.isNull(o2)) {
continue;
}
if (null == o1 || null == o2) {
setResult(o1, o2, name, label, list);
continue;
}
if (compareField(o1, o2)) {
setResult(o1, o2, name, label, list);
}
}
} else {
throw new Exception("比较的对象类型不一致");
}
return list;
} catch (Exception e) {
throw new Exception("对象比较失败", e);
}
}
/**
* 获取需要对比的字段
*
* @param objectClass
* @return
*/
private static List<String> getCompareFields(Class objectClass) {
Field[] fields = objectClass.getDeclaredFields();
List<String> map = new ArrayList<>();
for (Field f : fields) {
boolean annotationPresent2 = f.isAnnotationPresent(ObjectCompare.class);
if (annotationPresent2) {
map.add(f.getName());
}
}
return map;
}
/**
* 获取实体类字段的description
*
* @param clazz
* @return
*/
private static Map<String, String> getFieldSwaggerValue(Class clazz) {
Field[] fields = clazz.getDeclaredFields();
Map<String, String> map = new HashMap<>();
for (Field f : fields) {
boolean annotationPresent2 = f.isAnnotationPresent(ObjectCompare.class);
if (annotationPresent2) {
ObjectCompare name = f.getAnnotation(ObjectCompare.class);
String nameStr = name.value();
map.put(f.getName(), nameStr);
}
}
return map;
}
/**
* 比较字段
*
* @param o1 对象1
* @param o2 对象2
* @return boolean
**/
private static boolean compareField(Object o1, Object o2) {
boolean sign = false;
Object ot = null;
if (!Objects.isNull(o1)) {
ot = o1;
} else if (!Objects.isNull(o2)) {
ot = o2;
}
if (ot instanceof String) {
sign = !o1.equals(o2);
} else if (ot instanceof BigDecimal) {
sign = ((BigDecimal) o1).compareTo((BigDecimal) o2) != 0;
} else if (ot instanceof Integer) {
sign = ((Integer) o1).compareTo((Integer) o2) != 0;
} else if (ot instanceof Boolean) {
sign = ((Boolean) o1).compareTo((Boolean) o2) != 0;
} else if (ot instanceof Long) {
sign = ((Long) o1).compareTo((Long) o2) != 0;
} else if (ot instanceof LocalDateTime) {
sign = !((LocalDateTime) o1).isEqual((LocalDateTime) o2);
} else if (ot instanceof Date) {
sign = ((Date) o1).compareTo((Date) o2) != 0;
}
return sign;
}
/**
* 设置结果
*
* @param o1 对象1
* @param o2 对象2
* @param name 描述
* @param label 标签
* @param list 列表
**/
private static void setResult(Object o1, Object o2, String name, String label, List<ComparisonResult> list) {
ComparisonResult result = new ComparisonResult();
result.setKey(name);
result.setPrevious(o1);
result.setLater(o2);
result.setLabel(label);
list.add(result);
}
3.对比工具方法
代码如下(示例):
/**
* 动态给Java对象指定的属性赋值
*
* @param obj 要设置值的对象
* @param fieldName 要设置值的属性名称
* @param value 要设置的值
*/
public static void setFieldValueByName(Object obj, String fieldName, Object value) {
try {
// 获取obj类的字节文件对象
Class<? extends Object> c = obj.getClass();
// 获取该类的成员变量
Field field = c.getDeclaredField(fieldName);
// 取消语言访问检查
field.setAccessible(true);
// 给变量赋值
field.set(obj, value);
} catch (Exception e) {
log.error(e.getMessage());
}
}