如何使用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 ...
随机推荐
- windows 抓hash获取管理员密码
webshell 找能执行权限的目录上传 C:\Windows\System32\config\sam 内有windows 密码 利用工具把密码抓出来 samcopy 直接抓取 GetHASHES.e ...
- java学习2-数据类型和运算符
1.数据类型分类 java是强类型语言:a.所有的变量必须先声明后使用 b.指定类型的变量只能接受类型与之匹配的值 java语言支持的类型分为两类:基本类型和引用类型. 基本类型:包括boolean类 ...
- 微信小程序——获取formid
小程序对模板消息推送做了相应的限制:如果用户主动触发小程序表单提交1次,小程序可在7天内向用户主动推送1条模版消息,如果用户通过小程序完成支付,小程序可在7天内向用户主动推送3条模版消息.(formi ...
- 个人考场VIM配置
前言 这个是我个人使用的Vim配置.双引号杠掉的部分是关于光标行列高亮(觉得难受而杠)和输入左括号同时打上右括号的(不习惯),如果要启用的话去掉引号即可. 将以下要启用的输入到$“./vimrc”$中 ...
- 刷14道leetcode的总结
引子 为什么我要刷leetcode?换工作?不是!那是?玩!巴菲特的双目标清单系统,基本方法是列两个清单,一个是职业生涯最重要的目标(不超过5个),另一个是比较重要的目标.对于比较重要的目标,要像躲避 ...
- CheckBox多选
前台: <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> & ...
- django-模型之从数据库获取数据(二)
1.获取一条数据(字段值必须唯一) 2.条件查询filter 3.排除查询exclude 4.链式查询 5.查询后进行排序order_by 6.按字段查询values 7.插入数据create 8.数 ...
- Java内存模型(JMM)详解
在Java JVM系列文章中有朋友问为什么要JVM,Java虚拟机不是已经帮我们处理好了么?同样,学习Java内存模型也有同样的问题,为什么要学习Java内存模型.它们的答案是一致的:能够让我们更好的 ...
- Mac OS 简易U盘重装系统 亲测
Mac OS 简易U盘重装系统 亲测 亲测可用!简单方便,本文描述尽可能详细,如有疑问欢迎留言or微信咨询:523331232 如有帮助欢迎点赞! (一)制作MacOS系统U盘 [步骤1 准备U盘] ...
- redis面试题及答案
1. Redis有哪些数据结构? 2. 使用过Redis分布式锁么,它是什么回事? 3. 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来? ...