SpringData JPA save和saveAndFlush方法 以及实际应用的几个问题

2024-01-31 23:08

本文主要是介绍SpringData JPA save和saveAndFlush方法 以及实际应用的几个问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

  最近的工作持久层是用spirngData JPA 来做的

  这篇文章主要解决两个问题,第一个是save方法,如果是更新操作,会丢失之前原来已经有的字段的值。第二个问题是使用save方法并不能拿到我们想要的id 的问题。

 

 # # 首先一个常用的方法 save方法

  这个方法可以更新,也可以插入一条数据,但是在使用前我们要搞明白 save 的具体的工作机制。

  具体机制:

  • 使用save方法的时候,如果数据库中没有这条数据,是根据主键进行插入一条数据的操作。
  • 使用save方法的时候,如果数据库中已经存在这条数据的时候,是进行更新操作。这里有一个疑问,到底是直接覆盖原来已有的字段,但是只更新发生改变的字段?
  • 使用save方法的时候,需要注意到返回值的问题,返回值就是一个保存的对象,但是如果想要从这个返回值中获取一个ID ,这是做不到的。疑问又来了,不是插入,并返回插入这个对象吗,怎么就没有这个id呢。 这个问题在下边解决。

  使用save方法的问题,在save更新的时候,发生改变的会更新,没发生改变的会置为空。这句话的准确性,我保留疑问,具体    我还没有去测试,具体等我测试完,这块再改。 我看到这句话是从这篇文章上:                https://blog.csdn.net/weixin_38809962/article/details/81478635

   上边标注出来的问题我又看了好几个文章,这个问题是一定存在的。对于这个问题再看一下下边的文章。

  https://segmentfault.com/q/1010000010552860/a-1020000010567065

  从文章中我们知道,其实save方法,就是直接保存一个对象,这个操作是覆盖(我说的是在这个ID已经存在的情况下,否则及就是一个插入操作,没有任何疑问)举个例子,假如这个数据库已经有此ID 的数据,并且这条数据有十个字段。其中五个字段一已经有值了。现在要save操作,但是现在恰恰要保存没有值的这几个字段,我们直接用save,发现了这样的问题,本来有值的几个字段没有了。这不是我们想要的结果。真的想要达到我们想要的结果,应该先查询一次,如果有就将查到的合并到要save 的实体类中去。这样才能做到,十个字段全有值,不丢失已经有的字段。

# #   解决从返回值中拿不到 ID 的问题,应该先来区分一下 save方法 和 saveAndFlush 方法

   下边这块内容,参考https://blog.csdn.net/NathanniuBee/article/details/90482101

  On saveAndFlush, changes will be flushed to DB immediately in this command. With save, this is not necessarily true, and might stay just in memory, until flush or commit commands are issued.

   在saveAndFlush上,此命令中的更改将立即刷新到DB。使用save,就不一定了,它可能只暂时保留在内存中,直到发出flush或commit命令。

    这就是问题的根源,为什么拿不到 ID

  But be aware, that even if you flush the changes in transaction and do not commit them, the changes still won’t be visible to the outside transactions until the commit in this transaction.

  但是要注意的是,即使在事务中刷新了更改并且未提交它们,这些更改对于外部事务仍然不可见,直到,提交这个事务。

  In your case, you probably use some sort of transactions mechanism, which issues commit command for you if everything works out fine.

在您的情况下,您可能使用某种事务机制,如果一切正常,它会为您发出commit命令。

 # # 经验:

  比如在我们得项目中,保存一条数据后,我又想立马用到这条数据得id,因为实体类是配置了uuid自动生成,所以使用saveAndFlush()方法就可以立即获取到这条数据得id。但是如果用sava()方法,你不flush()或者commit,你得数据是暂时只在内存中保存,所以此时这条数据是没有主键id的.

提交事务后数据插入进数据库,要想在事务提交之前避免缓存插入数据库需要在执行完save操作调用flush方法或者直接执行saveAndFlush方法即可

这篇关于SpringData JPA save和saveAndFlush方法 以及实际应用的几个问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/665349

相关文章

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja