业务场景
更新User
信息后,需要收集哪些字段的哪些值被更新了。
思路
比较originUser
和newUser
,收集值不同的属性以及变化前后的值。
代码实现
public static Map<String, Map<String, Object>> getChange(Object originObject, Object newObject) {
// 存在为null比价就没意义了
if (ObjectUtils.anyNull(originObject, newObject)) {
return new HashMap<>();
}
// 不同类型无法比较
if (ObjectUtils.notEqual(originObject.getClass(), newObject.getClass())) {
return new HashMap<>();
}
// 内容都相等所以没必要比较
if (Objects.deepEquals(originObject, newObject)) {
return new HashMap<>();
}
Map<String, Map<String, Object>> res = Maps.newHashMap();
Field[] declaredFields = originObject.getClass().getDeclaredFields();
for (Field field : declaredFields) {
// 检查Field是否为合成字段、如果该字段是合成字段则不进行比较
if (field.isSynthetic()) {
continue;
}
// serialVersionUID适用于java序列化机制,非业务属性
if ("serialVersionUID".equals(field.getName())) {
continue;
}
// 实现方式1
// field.setAccessible(true);
// Object o = field.get(originObject);
// Object n = field.get(originObject);
// 实现方式2
PropertyDescriptor propertyDescriptor = null;
try {
propertyDescriptor = new PropertyDescriptor(field.getName(), originObject.getClass());
Method readMethod = propertyDescriptor.getReadMethod();
Object originValue = readMethod.invoke(originObject);
Object newValue = readMethod.invoke(newObject);
if (!Objects.deepEquals(originValue, newValue)) {
// 值不相等的话记录属性和值
HashMap<String, Object> keyValue = new HashMap();
keyValue.put("origin", originValue);
keyValue.put("new", newValue);
res.put(field.getName(), keyValue);
}
} catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
log.error("getChange occur error" + e.getMessage());
}
}
return res;
}
测试验证
public class MethodUtilsTest {
@Test
public void getChangeNoChange() {
User user1 = new User();
user1.setName("user2");
user1.setAge("19");
user1.setNum("123456");
User user2 = new User();
user2.setName("user2");
user2.setAge("19");
user2.setNum("123456");
Map<String, Map<String, Object>> change = MethodUtils.getChange(user1, user2);
Assert.assertEquals("{}", change.toString());
}
@Test
public void getChangeWithChange() {
User user1 = new User();
user1.setName("user1");
user1.setAge("19");
user1.setNum("123456");
User user2 = new User();
user2.setName("user2");
user2.setAge("18");
user2.setNum("123457");
Map<String, Map<String, Object>> change = MethodUtils.getChange(user1, user2);
Assert.assertEquals("{num={new=123457, origin=123456}, name={new=user2, origin=user1}, age={new=18, origin=19}}", change.toString());
}
@Data
static class User {
private String name;
private String age;
private String num;
}
}
参考
对象被更新后、获取更新了的属性和值