SpringBoot通过自定义注解+反射机制比较两个对象不同的属性值
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;
}
}