1.自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ForUpdate {
String fieldName() default "";
}
2.给需要对比的字段加上注解
@Data
@Builder
public class CompareRes {
private Long id; //不需要记录变化的字段,无需添加注解 @ForUpdate
@ForUpdate(fieldName = "姓名") //需要记录变化的字段,需添加注解@ForUpdate
private String name;
@ForUpdate(fieldName = "年龄")
private Integer age;
}
3.创建对比后放入的对象
/**
* 对象对比
* @param <T>
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ObjectContrastBO<T> {
/**
* 修改前对象
*/
private T beforeObject;
/**
* 修改后对象
*/
private T afterObject;
}
4.添加对比工具类
public class BeanUtil {
/**
* 获取变更前内容和变更后内容
* @param oldBean 更改前的Bean
* @param newBean 更改后的Bean
* @param <T>
* @return
*/
public static <T> ObjectContrastBO getChangedFields(T oldBean, T newBean){
Field[] fields = newBean.getClass().getDeclaredFields();
ObjectContrastBO objectContrastBO = new ObjectContrastBO<>();
for(Field field : fields) {
field.setAccessible(true);
if (!field.isAnnotationPresent(ForUpdate.class)) {
continue;
}
try {
Object oldValue = field.get(oldBean);
Object newValue = field.get(newBean);
if(Objects.equals(newValue, oldValue)) {
field.set(newBean, null);
field.set(oldBean, null);
}
} catch (Exception e) {
throw new RuntimeException("比较修改前后数据出错");
}
}
objectContrastBO.setBeforeObject(oldBean);
objectContrastBO.setAfterObject(newBean);
return objectContrastBO;
}
}
field.getAnnotation(ForUpdate.class).fieldName(); //获取字段名称
5.获取对比的对象
CompareRes beforeCompare = convertCompareRes(beanA);//转换对象
CompareRes afterCompare = convertCompareRes(beanB);
ObjectContrastBO<CompareRes> objectContrastBO = BeanUtil.getChangedFields(beforeCompare,afterCompare);
获取对比后的数据,相同的字段返回值为空,前端判断后展示非空