问题描述

在更新数据时,有时候我们只需要更新一部分字段,其他字段保持不变。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更新局部字段的更多相关文章

  1. 关于Spring Data JPA更新部分字段的问题

    1.问题背景 个人比较喜欢Spring data JPA,这次的问题是在实体类中使用List类型作为字段,JPA也提供了操作的方法,即使用@ElementCollection注解,网上对于JPA的知识 ...

  2. spring data jpa查询部分字段、多余附加字段

    spring data jpa查询部分字段 第一种方法:使用 model 查询时转化 首先建立一个 model ,写上自己想要查询的字段,然后写上构造函数,这步很重要,因为spring jpa 转化时 ...

  3. Spring Date JPA 更新部分字段

    在Spring Data JPA 中,新增和更新操作都是用save()的方式进行,JPA是通过什么方法来知道我们是要进行insert还是update呢? 经过测试,JPA对程序调用的save()方法判 ...

  4. spring data jpa自定义bean字段映射

    当遇到复杂多表查询时,并且同时还需要确保查询性能,此时则需要使用自定义sql查询,然而spring data jpa对于自定义sql则需使用查询需要在对应的bean中做太多的配置映射,我尝试了一下,最 ...

  5. spring data jpa 查询部分字段列名无效问题

    spring data jpa原生sql查询问题,我只要表其中的几个字段的值,本以为写个原生sql,拿实体类对象去接没问题 结果列名无效,测试了一下,把返回值类型改成List<Object> ...

  6. Spring Data Jpa 更新操作

    第一步,通过Repository对象把实体根据ID查询出来 第二部,往查出来的实体对象进行set各个字段 第三步,通过Repository接口的save方法进行保存 保存和更新方式(已知两种) 第一种 ...

  7. spring data jpa 查询自定义字段,转换为自定义实体

    目标:查询数据库中的字段,然后转换成 JSON 格式的数据,返回前台. 环境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2 背景:首先建立 ...

  8. 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 ...

  9. sping data jpa 共享主键 OneTonOne 延时加载

    当我们使用spring boot创建项目时,系统默认使用的是如下parent. <parent> <groupId>org.springframework.boot</g ...

随机推荐

  1. 概念理解:boost::asio::io_service

    IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service i ...

  2. Knative 实战:基于 Kafka 实现消息推送

    作者 | 元毅 阿里云智能事业群高级开发工程师 导读:当前在 Knative 中已经提供了对 Kafka 事件源的支持,那么如何基于 Kafka 实现消息推送呢?本文作者将以阿里云 Kafka 产品为 ...

  3. 1.7.3.1版本ride乱码的解决方法

    现象: 解决方式: 修改文件\Python36\Lib\site-packages\robotide\contrib\testrunner\testrunner.py 将latin1修改为mbcs 然 ...

  4. 11.Linux用户特殊权限

    1.特殊权限概述 前面我们已经学习过 r(读).w(写). x(执行)这三种普通权限,但是我们在査询系统文件权限时会发现出现了一些其他权限字母,比如: 2.特殊权限SUID set uid 简称sui ...

  5. HTTP使用get,post方式连接

    在项目中使用了http的get和post方式连接,发送传输数据: public static String doGet(String httpUrl) { HttpURLConnection conn ...

  6. Nginx初学(一)安装与运行

    1.下载nginx安装包 nginx-1.6.3.tar.gz并复制安装包到 /usr/local/software中 2.安装依赖包,命令如下: yum -y install gcc-c++(需要等 ...

  7. 把图片在word中显示

    如下: //放入word中 #region word ThreadPool.QueueUserWorkItem(//使用线程池 (P_temp) =>//使用lambda表达式 { G_wa = ...

  8. 10 python学习笔记-操作数据库(十)

    在功能.接口测试中,常常需要通过数据库的操作,来准备数据.检测环境及核对功能.接口的数据库操作是否正确. 在自动化测试中,就需要我们用代码连接数据库自动完成数据准备. 环境检查及数据库断言的功能.数据 ...

  9. 树莓派上搭建arduino命令行开发环境

    -------------还是博客园上面的格式看这舒服,不去新浪了------------- 为什么要在树莓派上开发arduino呢?总要把树莓派用起来嘛,不然老吃灰. 树莓派使用SSH时没有图形界面 ...

  10. 说说babel

    一.什么是babel 二.如何配置 三.配置babel-polyfill 一.什么是babel The compiler for writing next generation JavaScript. ...