解决springjpa的局部更新字段问题
问题描述:
使用springjpa更新数据时,有时候我们需要更新部分字段,对已有的内容保持不变,通常我们可以通过spring提供的bean工具类beanutils来实现
解决方法:
beanutils复制对象,beanutils中的构造方法属性中可以通过传入更新时忽略的属性值来实现选择性复制原对象的字段。更新部分字段时,我们仅需要传入复制后的字段即可。
解析和实现:
beanutils的构造方法:
具体更新部分字段的步骤:
查询出待更新对象的原有信息
通过传入的更新的象去复制产生一个新对象,其中新对象中为null的字段不需要更新。
执行更新操作,操作对象时步骤2得出的复制对象。
代码如下:
public result update(@requestbody appscene appscene, @pathvariable string id ){ appscene target = appsceneservice.findbyid(id); //数据库查出待更新对象 beanutils.copyproperties(appscene,target,getnullpropertynames(appscene)); //使用更新对象的非空值去覆盖待更新对象 appsceneservice.update(target ); //执行更新操作 return new result(true,statuscode.ok,"修改成功"); }
其中涉及的getnullpropertynames方法作为工具类存在,具体如下:
public static string[] getnullpropertynames (object source) { final beanwrapper src = new beanwrapperimpl(source); java.beans.propertydescriptor[] pds = src.getpropertydescriptors(); set<string> emptynames = new hashset<string>(); for(java.beans.propertydescriptor pd : pds) { object srcvalue = src.getpropertyvalue(pd.getname()); if (srcvalue == null) emptynames.add(pd.getname()); } string[] result = new string[emptynames.size()]; return emptynames.toarray(result); }
更新:
这是之前刚开始学习框架的时候遇到的问题,其实这个问题spring早就提供了对应的方法去解决,它提供了对应bean拷贝的方法beanutils.copyproperties,通过传入不同的值决定是否要忽略非空属性值的拷贝,现在已经没有必要自己手写了。
补充:java jpa选择性更新、部分字段更新工具类
使用jpa自带的save方法更新实体类时,会覆盖数据库中实体类原有内容。如果我们只想更新一部分字段或是选择性的更新,就只能另辟蹊径了。
这个工具类很好地弥补了这个不足,对于待更新实体类中有内容的字段会更新,为空的字段会采用原数据库中内容,下面是工具类代码(附使用方法)。
工具类代码:
import org.springframework.beans.beanwrapper; import org.springframework.beans.beanwrapperimpl; import java.util.hashset; import java.util.set; /** * jpa 部分字段更新方法 */ public class updatecolumnutil { public static string[] getnullpropertynames(object source) { final beanwrapper src = new beanwrapperimpl(source); java.beans.propertydescriptor[] pds = src.getpropertydescriptors(); set<string> emptynames = new hashset<>(); for (java.beans.propertydescriptor pd : pds) { object srcvalue = src.getpropertyvalue(pd.getname()); if (srcvalue == null) emptynames.add(pd.getname()); } string[] result = new string[emptynames.size()]; return emptynames.toarray(result); } }
使用方法:
//首先从数据库查出待更新对象 customer target = customerservice.findbyid(customer.getcustid()); //使用更新对象的非空值去覆盖待更新对象 beanutils.copyproperties(customer, target, updatecolumnutil.getnullpropertynames(customer)); //执行更新操作 save = customerservice.save(target);
这样一个映射就完成我们的需求了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。
上一篇: SpringBoot2 Jpa 批量删除功能的实现
下一篇: 孙权那么信任陆逊,为何还要多次羞辱他?
推荐阅读
-
Python pip的自动更新升级失败问题解决方案
-
解决asp.net mvc UpdateModel更新对象后出现null问题的方法
-
如何解决ASP.NET新增时多字段取值的问题
-
SQL order by ID desc/asc加一个排序的字段解决查询慢问题
-
解决vuecli3.0热更新失效的问题
-
Oracle 11g的密码更新 Oracle 11g密码180过期问题解决方案
-
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
-
解决PySide+Python子线程更新UI线程的问题
-
PDO取Oracle lob大字段,当数据量太大无法取出的问题的解决办法
-
解决vue select当前value没有更新到vue对象属性的问题