如何使用Sping Data JPA更新局部字段
问题描述
在更新数据时,有时候我们只需要更新一部分字段,其他字段保持不变。Spring Data JPA并未提供现成的接口,直接使用save()更新会导致其他字段被Null覆盖掉。
解决办法
通常有两种方法解决此问题:
1、通过传入对象的id,从数据库中查询得到原始对象,然后将要修改的字段封装到原始对象中。再以封装后的对象为参数进行save()。
代码如下:
public FrontResult update(Evaluation evaluation) {
// 从数据库中获取对象
Evaluation original = evaluationRepo().findById(evaluation.getId());
// 复制想要更改的字段值
BeanUtils.copyProperties(evaluation, original, getNullPropertyNames(evaluation));
// 更新操作
evaluationRepo().save(original);
return FrontResult.init(FrontResult.SUCCEED, "更新成功");
}
使用的工具类如下(用于获取未被修改的字段名):
public class UpdateUtil {
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);
}
}
2、通过注解@Query自己实现sql语句。
注意:
在执行update或者delete方法时,必须加上注解@Modifying 和 @Transactional。
此处的Test要使用实体的类名,不是数据库中的表名。
代码如下:
@Modifying
@Transactional
@Query("update Test a set " +
"a.name = CASE WHEN :#{#testAre.name} IS NULL THEN a.name ELSE :#{#testAre.name} END ," +
"a.age = CASE WHEN :#{#testAre.age} IS NULL THEN a.age ELSE :#{#testAre.age} END ," +
"a.insertTime = CASE WHEN :#{#testAre.insertTime} IS NULL THEN a.insertTime ELSE :#{#testAre.insertTime} END ," +
"a.spare = CASE WHEN :#{#testAre.spare} IS NULL THEN a.spare ELSE :#{#testAre.spare} END " +
"where a.id = :#{#testAre.id}")
int update(@Param("testAre") TestAre testAre);
一般字段比较多时我会选第一种方式,虽然多查了一次数据库,但是省键盘。
如何使用Sping Data JPA更新局部字段的更多相关文章
- 关于Spring Data JPA更新部分字段的问题
1.问题背景 个人比较喜欢Spring data JPA,这次的问题是在实体类中使用List类型作为字段,JPA也提供了操作的方法,即使用@ElementCollection注解,网上对于JPA的知识 ...
- spring data jpa查询部分字段、多余附加字段
spring data jpa查询部分字段 第一种方法:使用 model 查询时转化 首先建立一个 model ,写上自己想要查询的字段,然后写上构造函数,这步很重要,因为spring jpa 转化时 ...
- Spring Date JPA 更新部分字段
在Spring Data JPA 中,新增和更新操作都是用save()的方式进行,JPA是通过什么方法来知道我们是要进行insert还是update呢? 经过测试,JPA对程序调用的save()方法判 ...
- spring data jpa自定义bean字段映射
当遇到复杂多表查询时,并且同时还需要确保查询性能,此时则需要使用自定义sql查询,然而spring data jpa对于自定义sql则需使用查询需要在对应的bean中做太多的配置映射,我尝试了一下,最 ...
- spring data jpa 查询部分字段列名无效问题
spring data jpa原生sql查询问题,我只要表其中的几个字段的值,本以为写个原生sql,拿实体类对象去接没问题 结果列名无效,测试了一下,把返回值类型改成List<Object> ...
- Spring Data Jpa 更新操作
第一步,通过Repository对象把实体根据ID查询出来 第二部,往查出来的实体对象进行set各个字段 第三步,通过Repository接口的save方法进行保存 保存和更新方式(已知两种) 第一种 ...
- spring data jpa 查询自定义字段,转换为自定义实体
目标:查询数据库中的字段,然后转换成 JSON 格式的数据,返回前台. 环境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2 背景:首先建立 ...
- spring data jpa 查询部分字段
@Query("select new map(ah as ah,salq as sqlq,yg as yg, bg as bg,ay as ay) FROM Aj where ahdm=?1 ...
- sping data jpa 共享主键 OneTonOne 延时加载
当我们使用spring boot创建项目时,系统默认使用的是如下parent. <parent> <groupId>org.springframework.boot</g ...
随机推荐
- Vulnhub靶场渗透练习(一) Breach1.0
打开靶场 固定ip需要更改虚拟机为仅主机模式 192.168.110.140 打开网页http://192.168.110.140/index.html 查看源代码发现可以加密字符串 猜测base64 ...
- 百万年薪python之路 -- 带颜色的print
带颜色的print print输出带颜色的方法详解 书写格式: 开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m 注意:开头部分的三个参数:显示方式,前景色,背景色是可 ...
- JVM 启动调优总结
启动命令 格式: java -jar 命令行参数 jar包路径 .示例如下 java -Dfile.encoding=utf-8 -jar -XX:MetaspaceSize=128m -XX:Max ...
- SpringBoot学习(三)探究Springboot自动装配
目录 什么是自动装配 何时自动装配 原理分析 注:以下展示的代码springboot的版本为2.0.3版.因源码过长,大家选择展开代码 ㄟ( ▔, ▔ )ㄏ 什么是自动装配 自动装配还是利用了Spri ...
- dom 创建时间
下面讲述如何在页面生成一个装有日期的盒子 首先写出一个日期的函数进行赋值使用document.createElement创建一个文档节点div,然后将时间函数输出在div之中,利用document.b ...
- mysql全局变量和局部变量
全局变量和局部变量 在服务器启动时,会将每个全局变量初始化为其默认值(可以通过命令行或选项文件中指定的选项更改这些默认值).然后服务器还为每个连接的客户端维护一组会话变量,客户端的会话变量在连接时使用 ...
- apply 、 call 、 bind的用法
1.apply 方法 apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法. apply方法最多只能有两个参数——新 ...
- Web for pentester_writeup之XML attacks篇
Web for pentester_writeup之XML attacks篇 XML attacks(XML攻击) Example 1 - XML外部实体注入(XXE) Payload http:// ...
- SSH隧道的使用
合作部门提供的 redis 集群,kafka 集群,限制条件:无 vpn,仅能通过特定跳板机(无 root 权限)连接调试开发. 想要实现:本地开发连接其 redis 集群,kafka 集群进行开发调 ...
- JDBC向数据库中写数据
package MYSQK; import java.sql.*; /** * PreparedStatement 对象可以对sql语句进行预编译,预编译的信息会存在存储该对象中,当相同的sql语句再 ...