|
@@ -0,0 +1,82 @@
|
|
|
|
|
+package com.jzg.commons.util.comparble;
|
|
|
|
|
+
|
|
|
|
|
+import com.jzg.commons.aop.aspect.DiffProperty;
|
|
|
|
|
+import lombok.SneakyThrows;
|
|
|
|
|
+import org.springframework.util.ConcurrentReferenceHashMap;
|
|
|
|
|
+
|
|
|
|
|
+import java.lang.reflect.Field;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 对象比较工具类
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author dongxin
|
|
|
|
|
+ */
|
|
|
|
|
+public class DiffUtils {
|
|
|
|
|
+
|
|
|
|
|
+ private static final Map<Class<?>, Map<String, Field>> DIFF_PROPERTY_CACHE = new ConcurrentReferenceHashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 比较两个相同类型的对象属性之间的差异
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a 对象A
|
|
|
|
|
+ * @param b 对象B
|
|
|
|
|
+ * @param <T> 对象类型
|
|
|
|
|
+ * @return 差异列表
|
|
|
|
|
+ * @throws IllegalAccessException
|
|
|
|
|
+ */
|
|
|
|
|
+ @SneakyThrows
|
|
|
|
|
+ public static <T> List<DiffResult> diff(T a, T b) {
|
|
|
|
|
+ if (equals(a, b)) {
|
|
|
|
|
+ return Collections.EMPTY_LIST;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取并缓存一个类中需要对比的字段
|
|
|
|
|
+ Map<String, Field> cachedDiffPropertyMap = DIFF_PROPERTY_CACHE.computeIfAbsent((a != null ? a : b).getClass(),
|
|
|
|
|
+ clazz -> {
|
|
|
|
|
+ Map<String, Field> diffPropertyMap = new HashMap<>();
|
|
|
|
|
+ for (Field field : clazz.getDeclaredFields()) {
|
|
|
|
|
+ DiffProperty diffProperty = field.getAnnotation(DiffProperty.class);
|
|
|
|
|
+ if (diffProperty != null) {
|
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
|
+ String name = diffProperty.name();
|
|
|
|
|
+ if (name.isEmpty()) {
|
|
|
|
|
+ name = field.getName();
|
|
|
|
|
+ }
|
|
|
|
|
+ diffPropertyMap.put(name, field);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return diffPropertyMap;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 新老对象,属性值进行对比,并将对比结果,不同的进行返回
|
|
|
|
|
+ List<DiffResult> diffResultList = new ArrayList<>();
|
|
|
|
|
+ for (Map.Entry<String, Field> fieldEntry : cachedDiffPropertyMap.entrySet()) {
|
|
|
|
|
+ Field field = fieldEntry.getValue();
|
|
|
|
|
+ // field.get(a) 获取a对象field这个属性名的属性值!
|
|
|
|
|
+ Object aValue = a == null ? null : field.get(a);
|
|
|
|
|
+ Object bValue = b == null ? null : field.get(b);
|
|
|
|
|
+ if (!equals(aValue, bValue)) {
|
|
|
|
|
+ diffResultList.add(new DiffResult(field.getName(), fieldEntry.getKey(), aValue, bValue));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return diffResultList;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 比较两个对象是否相同
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a 对象A
|
|
|
|
|
+ * @param b 对比B
|
|
|
|
|
+ * @return 相同返回true,不同返回false
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean equals(Object a, Object b) {
|
|
|
|
|
+ if (a == null) {
|
|
|
|
|
+ return b == null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (a == b) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return a.equals(b);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|