SpringBoot通过自定义注解+反射机制比较两个对象不同的属性值

时间:2025-03-12 09:03:50
import org.springframework.util.StringUtils; import java.lang.reflect.Field; import java.util.*; /** * @Author: * @Date: 2023/1/9 11:27 * @Description: 字段比较 **/ public class FieldComparisonUtil { /** * 直接返回一个新的对象,并且对象的值 只有被修改的部分 * * @param old * @param source * @param isParent * @param target 目标对象 * @return */ public static void compareFieldsToNewObject(Object old, Object source, Boolean isParent, Object target) { Map<String, Object> map = compareFields(old, source, isParent); if (map.size() > 0) { try { List<Field> fieldList = new ArrayList<>(); Class<?> clazz = target.getClass(); // 获取字段 Field[] fields = clazz.getDeclaredFields(); fieldList.addAll(Arrays.asList(fields)); // 获取父类字段 if (isParent) { Class<?> superclass = clazz.getSuperclass(); Field[] parentFields = superclass.getDeclaredFields(); fieldList.addAll(Arrays.asList(parentFields)); } for (Field field : fieldList) { field.setAccessible(true); String name = field.getName(); if (map.get(name) != null) { field.set(target, map.get(name)); } } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } } /** * @param old 进行属性比较的原始数据 * @param source 进行属性比较的新数据 * @param isParent 是否存在父类 * @return */ public static Map<String, Object> compareFields(Object old, Object source, Boolean isParent) { Map<String, Object> map = new HashMap<>(8); try { // 只有两个对象都是同一类型的才有可比性 if (old.getClass() == source.getClass()) { List<Field> fieldList = new ArrayList<>(); Class<?> clazz = old.getClass(); // 获取字段 Field[] fields = clazz.getDeclaredFields(); fieldList.addAll(Arrays.asList(fields)); // 获取父类字段 if (isParent) { Class<?> superclass = clazz.getSuperclass(); Field[] parentFields = superclass.getDeclaredFields(); fieldList.addAll(Arrays.asList(parentFields)); } // 这里就是所有的属性了 for (Field field : fieldList) { boolean annotationPresent = field.isAnnotationPresent(FieldComparison.class); // 没有注解的字段表示,不参与比较 if (!annotationPresent) { continue; } field.setAccessible(true); // 属性名 String fieldName = field.getName(); // 在old上调用get方法等同于获得old的属性值 Object objBefore = field.get(old); // 在source上调用get方法等同于获得source的属性值 Object objAfter = field.get(source); // 比较字段同时为空时,则表示是一样的值 if (objAfter instanceof String) { if (StringUtils.isEmpty(objBefore) && StringUtils.isEmpty(objAfter)) { continue; } } // 比较是否一致 boolean equals = Objects.equals(objBefore, objAfter); // 不一致则进行记录 if (!equals) { if (objAfter != null) { /** * 如果要使用字符串记录,那么对特殊的数据,需要进行转换 if (objAfter instanceof Date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String formatDate = ((Date) objAfter); (fieldName, formatDate); } else if (objAfter instanceof LocalDateTime) { DateTimeFormatter formatter = ("yyyy-MM-dd HH:mm:ss"); String formatDate = ((LocalDateTime) objAfter).format(formatter); (fieldName, formatDate); } else if (objAfter instanceof LocalDate) { DateTimeFormatter formatter = ("yyyy-MM-dd"); String formatDate = ((LocalDate) objAfter).format(formatter); (fieldName, formatDate); } **/ map.put(fieldName, objAfter); } } } } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return map; } }