在我们日常开发过程中,从前端返回的对象中数据可能不是你所预期的那样!然而在Spring data jpa中,底层基础框架并没有针对实体属性的非空验证。如果你传递回来的实体中有属性为null,那么框架回忠心的将你已有的数据替换为null,而不是维持原样。
如何解决这样的问题,java的反射机制与广大的网友给我们提供了解决办法。
代码如下
public static boolean updateNotNullField(Object rawObject, Object newObject) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
//如果连个对象不一致。不进行更新字段值的操作
if (rawObject.getClass().getName() != newObject.getClass().getName()) {
return false;
}
//获取原始对象中的所有public方法
Method[] methods = rawObject.getClass().getDeclaredMethods();
//用于提取不包含指定关键词的方法
String regExpression = "^(get)(?!Id|CreateTime)(\\w+)";
Pattern pattern = Pattern.compile(regExpression);
Matcher m;
for (Method method : methods) {
m = pattern.matcher(method.getName());
//正则匹配以get开头,后面不能匹配Id、CreateTime这两个单词的方法
if (m.find()) {
Object o = method.invoke(newObject, null);
//忽略值为空的字段
if (o == null) {
continue;
}
//取出get方法名后面的字段名
String fieldName = m.group(2);
//找到该字段名的set方法
Method rawMethod = rawObject.getClass().getMethod("set" + fieldName, method.getReturnType());
//调用实体对象的set方法更新字段值
rawMethod.invoke(rawObject, o);
}
}
return true;
}
这个方法为我们提供了除开指定关键字的两个实体之间属性的重叠。也就是说,代码以rawObject为基础,将newObject中的非null值赋值给相同属性名的属性上。
但是这样的方法也只能用单层的实体,如果你的实体中还包含了其他的实体,那么这样的赋值方法是不能判断出你下层实体中的属性的。所以 如果你的实体中还包含了其他的实体,那么你最好做一个model来将你的实体解成单层,或者一层一层的去对比,如果你确实要用到上述的方法的话!
网友评论