Prechádzať zdrojové kódy

比对工具类的提交

dongxin 1 rok pred
rodič
commit
fd7564398b

+ 25 - 0
commons/src/main/java/com/jzg/commons/aop/aspect/DiffProperty.java

@@ -0,0 +1,25 @@
+package com.jzg.commons.aop.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 对比项属性注解
+ *
+ * 只有标记了此注解的属性才会进行对比
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DiffProperty {
+
+    /**
+     * 对比项名称
+     * <p>
+     * 如果不指定,则取字段的名称
+     *
+     * @return
+     */
+    String name() default "";
+}

+ 32 - 0
commons/src/main/java/com/jzg/commons/util/comparble/DiffResult.java

@@ -0,0 +1,32 @@
+package com.jzg.commons.util.comparble;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 比对返回的对象
+ *
+ * @author dongxin
+ */
+@Data
+@AllArgsConstructor
+public class DiffResult {
+    /**
+     * 字段名称
+     */
+    private String fieldName;
+    /**
+     * 对比项名称
+     */
+    private String propertyName;
+
+    /**
+     * 老对象的值
+     */
+    private Object oldValue;
+
+    /**
+     * 新对象的值
+     */
+    private Object newValue;
+}

+ 82 - 0
commons/src/main/java/com/jzg/commons/util/comparble/DiffUtils.java

@@ -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);
+    }
+}