// User 对象实体类 @Data @EqualsAndHashCode(callSuper = false) @ApiModel(value="用户对象", description="用户表") public class User { @ApiModelProperty(value = "用户id") private int id; @ApiModelProperty(value = "姓名") private String name; @ApiModelProperty(value = "年龄") private int age; @ApiModelProperty(value = "地址") private String address; }
// User 修改日志类
@Data @EqualsAndHashCode(callSuper = false) @ApiModel(value = "userUpdateLog对象", description = "用户修改日志表") public class UserUpdateLog { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "主键ID") private Long userLogId; @ApiModelProperty(value = "修改类型") private String modifyField; @ApiModelProperty(value = "修改前内容") private String beforeModification; @ApiModelProperty(value = "修改后内容") private String afterModification; }
// 正式代码测试类 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @RunWith(SpringRunner.class) public class demo1 { /** * JDK内省类库: * PropertyDescriptor类:(属性描述器) * PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法: * 1. getPropertyType(),获得属性的Class对象; * 2. getReadMethod(),获得用于读取属性值的方法; * 3. getWriteMethod(),获得用于写入属性值的方法; * 4. hashCode(),获取对象的哈希值; * 5. setReadMethod(Method readMethod),设置用于读取属性值的方法; * 6. setWriteMethod(Method writeMethod),设置用于写入属性值的方法 */ @Test public void test1(){ User beforeUser=new User(); beforeUser.setId(1); beforeUser.setName("小明"); beforeUser.setAge(20); beforeUser.setAddress("北京"); User afterUser=new User(); afterUser.setId(2); afterUser.setName("小黑"); afterUser.setAge(30); afterUser.setAddress("上海"); List<UserUpdateLog> userUpdateLogs = contrastObj(afterUser, beforeUser); System.out.println(userUpdateLogs); } public static List<UserUpdateLog> contrastObj(Object afterObj, Object beforeObj) { User afterUser = (User) afterObj; User beforeUser = (User) beforeObj; List<UserUpdateLog> updateLogList = Lists.newArrayList(); try { Class clazz = afterUser.getClass(); Field[] fields = afterUser.getClass().getDeclaredFields(); for (Field field : fields) { UserUpdateLog userUpdateLog = new UserUpdateLog(); if("serialVersionUID".equals(field.getName())){ continue; } //获取 clazz 类型中的 propertyName 的属性描述器 PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz); // 获得读取属性值的方法 getReadMethod() Method getMethod = pd.getReadMethod(); Object o1 = getMethod.invoke(afterUser); Object o2 = getMethod.invoke(beforeUser); String s1 = o1 == null ? "" : o1.toString();//避免空指针异常 String s2 = o2 == null ? "" : o2.toString();//避免空指针异常 //思考下面注释的这一行:会bug的,虽然被try catch了,程序没报错,但是结果不是我们想要的 // todo 我的理解 o1 o2 是object 类型 //if (!o1.toString().equals(o2.toString())) { if (!s1.equals(s2)) { userUpdateLog.setModifyField(field.getAnnotation(ApiModelProperty.class).value()); userUpdateLog.setBeforeModification(s2); userUpdateLog.setAfterModification(s1); updateLogList.add(userUpdateLog); } } } catch (Exception e) { System.out.println(e.getMessage()); } return updateLogList; }
// 控制台输出结果
[UserUpdateLog(userLogId=null, modifyField=用户id, beforeModification=1, afterModification=2), UserUpdateLog(userLogId=null, modifyField=姓名, beforeModification=小明, afterModification=小黑), UserUpdateLog(userLogId=null, modifyField=年龄, beforeModification=20, afterModification=30), UserUpdateLog(userLogId=null, modifyField=地址, beforeModification=北京, afterModification=上海)]