Spring JpaRepostory delete vs deleteInBatch

kul*_*uda 19 java spring spring-data

Spring中JpaRepostory delete(...)deleteInBatch(...)方法有什么区别?第二个"删除一个SQL语句中的项目",但从应用程序/数据库的角度来看它意味着什么?为什么存在两种具有相似结果的不同方法,何时使用一种或另一种更好?

编辑: 这同样也适用于deleteAll()deleteAllInBatch()...

Ben*_*rer 16

这里的答案并不完整!

首先,让我们检查文档

void deleteInBatch(Iterable<T> entities)
Deletes the given entities in a batch which means it will create a single Query.
Run Code Online (Sandbox Code Playgroud)

因此,“delete[All]InBatch”方法将使用 JPA 批量删除,例如“DELETE FROM table [WHERE ...]”。这可能更有效,但它有一些警告:

  • 这不会调用您可能拥有的任何 JPA/Hibernate 生命周期钩子 (@PreDelete)
  • 它不会级联到其他实体
  • 您必须清除持久性上下文或假设它已失效。

这是因为 JPA 会向数据库发出批量 DELETE 语句,绕过缓存等,因此无法知道哪些实体受到影响。

查看 Hibernate 文档

Spring Data JPA 中的实际代码

虽然我在这里找不到具体的文章,但我会推荐Vlad Mihalcea写的所有内容,以便更深入地了解 JPA。

TLDR:“inBatch”方法使用批量 DELETE 语句,它可以快得多,但有一些警告 bc。它们绕过 JPA 缓存。您应该真正了解它们的工作原理以及何时使用它们来受益。


Kur*_*ois 10

delete方法将在一次操作中删除您的实体.在deleteInBatch即将批量删除几个语句和删除它们为1个操作.

如果您需要大量删除操作,批量删除可能会更快.

  • 好的,我理解这一点.但它仍然没有回答为什么存在两种方法?现在每个人都希望更快更快地执行所有事情,所以为什么不使用eg.deleteAllInBatch实现作为deleteAll的默认实现,并且KISS整个JPARepository API. (3认同)
  • delete删除一个项目,deleteAll逐个删除所有项目(它调用"从<table>删除id =?"N次),deleteInBatch通过单个sql删除操作删除所有项目:"从<table>删除".我相信如果我们将它与delete()或deleteAll()进行比较,这对deleteInBatch没有性能影响 (3认同)
  • 因为批处理会对性能产生影响.它仅比来自特定数量的操作的单个查询更快. (2认同)
  • 这不是一个完整的答案。它非常简单,甚至不提供文档。我还没有研究过这一点,但我敢打赌,使用批处理方法将会跳过很多东西,例如应用程序提供的实体侦听器和持久性提供者的验证逻辑。 (2认同)

小智 8

deleteInBatch(...) 在日志中看起来像这样: DELETE FROM table_name WHERE (((((((? = id) OR (? = id)) OR (? = id)) OR (? = id)) OR (? = id)) OR (? = id)) OR (? = id))

如果要删除的数据量达到 SQL Server 查询的最大大小,这可能会导致出现问题: SQL Server 查询的最大大小?IN条款?有没有更好的方法

  • 已确认的大型 deleteInBatch 调用会导致 StackOverflowError。为了避免这种情况,应编写自定义查询以使用 IN 语句,或者应将批处理分成更小的块。 (2认同)