经常会遇到一些管理后台,需要详细的记录每次操作更新的内容,具体到字段,以及修改前修改后的内容;
利用反射写了一个通用工具类
定义一个简单的PO:
@Data
@NoArgsConstructor
public class SimplePO {
@Record(name = "唯一键")
private Integer id;
@Record(name = "名字")
private String name;
@Record(isRecord = false)
private String desc;
}
字段注解,能够有针对性的记录字段内容:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Record {
boolean isRecord() default true;
String name() default "";
}
工具类:
public class RecordUtil<T> {
public String record(Class<T> clazz,T newObj,T oldObj) throws IllegalAccessException {
if(oldObj.equals(newObj)){
return "";
}
StringBuffer sb = new StringBuffer();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
field.setAccessible(true);
boolean isHasAnnotation = field.isAnnotationPresent(Record.class);
if( !isHasAnnotation ){
continue;
}
Record record = field.getAnnotation(Record.class);
if(!record.isRecord()){
continue;
}
if(field.get(oldObj) == field.get(newObj)){
continue;
}
if(field.get(oldObj) != null){
String oldValue = String.valueOf(field.get(oldObj));
String newValue = String.valueOf(field.get(newObj));
String name = record.name();
String fieldName = field.getName();
if( !oldValue.equalsIgnoreCase(newValue)){
sb.append(name).append("(").append(fieldName).append(")").append("修改前:").append(oldValue).
append(" 修改后:").append(newValue).append("\n");
}
}else {
String newValue = String.valueOf(field.get(newObj));
String name = record.name();
String fieldName = field.getName();
sb.append(name).append("(").append(fieldName).append(")").append("修改前:").append("null").
append(" 修改后:").append(newValue).append("\n");
}
}
System.out.printf(sb.toString());
return sb.toString();
}
测试用例:
public static void main(String[] args) {
try {
SimplePO newPO = new SimplePO();
newPO.setId(1);
newPO.setName("测试");
newPO.setDesc("星期一");
SimplePO oldPO = new SimplePO();
oldPO.setId(2);
oldPO.setName("上线");
oldPO.setDesc("星期二");
System.out.printf("test");
RecordUtil<SimplePO> recordUtil = new RecordUtil<>();
recordUtil.record(SimplePO.class,newPO,oldPO);
System.out.printf("执行到这了");
} catch (Exception e) {
e.printStackTrace();
}
}
测试结果:
唯一键(id)修改前:2 修改后:1
名字(name)修改前:上线 修改后:测试