如何使用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 ...
随机推荐
- 常用函数-Linux文件操作
/************************************************************************ 函数功能:寻找文件夹下的某格式文件 std::vec ...
- 02jmeter-函数助手使用
示例:__Random函数 1.打开函数助手,并按提示写入value 2.引用.复制出${__Random(1,99,gp)}放到需要引用的地方 3.请求成功后可通过debug sampler查看变量 ...
- 百万年薪python之路 -- 基本数据类型
整数 -- 数字(int) 用于比较和运算 32位 2 ** 31 ~ 2 ** 31-1 64位 -2 ** 63 ~ 2 ** 63- 1 + - * / // ** % python2 整型 ...
- GO基础之闭包
一.闭包的理解 闭包是匿名函数与匿名函数所引用环境的组合.匿名函数有动态创建的特性,该特性使得匿名函数不用通过参数传递的方式,就可以直接引用外部的变量. 这就类似于常规函数直接使用全局变量一样,个人理 ...
- JavaWeb EL表达式 key为数值 Map取不到值
JavaWeb EL表达式 key为 Map取不到值 因为JSTL会把Integer,Byte,Short,Charactor都转成Long,这样就取不到值. 参见StackOverFlow的回答 ...
- 数据结构(四十)平衡二叉树(AVL树)
一.平衡二叉树的定义 平衡二叉树(Self-Balancing Binary Search Tree或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一 ...
- day3-02 python入门之基本的数据类型
目录 一.整型(int) 二.浮点型(float) 三.字符串类型(str) 字符串在python2和python3中的细微区别 四.复数 五.列表(list) 六.数据字典(dict) 定义方式 七 ...
- MarkDown时序图
时序图 语法 ```sequence ``` 标题 title: 我是标题 对象 participant A participant B as b-alias 交互 sequence A->B: ...
- 一:VSCode引入jupyter
1:安装 2:示例代码 #%% import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np x , , ) ...
- Linux的目录介绍
Linux的目录介绍 Linux系统以目录来组织和管理系统中的所有文件.Linux系统通过目录将系统中所有的文件分级.分层组织在一起,形成了Linux文件系统的树型层次结构.以根目录 “/” 为起点, ...