背景:需要记录操作的变更记录,修改后的对象与原对象进行比较会存在大量if的判断。 措施:使用Java反射比较两个对象的不同属性值,实现数据库修改操作的日志记录。
1、自定义注解,标识对象需要比较的字段
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CompareField {
String value();
}
2、在实体的指定字段上使用注解
@ApiModel(value="BcBuildingPark对象", description="园区表")
@Data
@TableName("building_park")
public class BuildingPark implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "园区id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@CompareField(value = "园区名称")
@ApiModelProperty(value = "园区名称")
private String name;
@ApiModelProperty(value = "园区所在区域id")
private Integer regionId;
@CompareField(value = "园区地址")
@ApiModelProperty(value = "园区地址")
private String address;
@CompareField(value = "园区所占面积")
@ApiModelProperty(value = "园区所占面积")
private BigDecimal area;
......
}
通过value表明修改字段的中文含义。
3、编写工具类
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class ObjectComparator {
public static Map<String, String> compare(Object oldObj, Object newObj) {
Map<String, String> result = new HashMap<>();
try {
// 获取所有字段
Field[] fields = oldObj.getClass().getDeclaredFields();
// 遍历所有字段
for (Field field : fields) {
// 如果字段被 @CompareField 注解标注
if (field.isAnnotationPresent(CompareField.class)) {
// 获取字段的中文名
String fieldName = field.getAnnotation(CompareField.class).value();
// 设置字段可访问
field.setAccessible(true);
// 获取字段的旧值和新值
Object oldValue = field.get(oldObj);
Object newValue = field.get(newObj);
// 如果值不相等
if (!Objects.equals(oldValue, newValue)) {
//BigDecimal单独判断
if (oldValue instanceof BigDecimal) {
BigDecimal oldV = (BigDecimal) oldValue;
BigDecimal newV = (BigDecimal) newValue;
if (oldV.compareTo(newV) == 0) {
continue;
}
}
// 将字段名和值添加到结果中
result.put(fieldName, "旧值:" + oldValue + " ~ 新值:" + newValue);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
4、执行调用
String detail = "修改楼宇:";
Map<String, String> compare = ObjectComparator.compare(buildingPark1, bcBuildingPark);
detail += compare.toString();
recordService.addBcBuildingParkRecord(bcBuildingPark,StatusConstant.PARK_UPDATE, detail);
return AjaxResult.success("修改楼宇园区成功");
5、结果展示