是否可以使用 JpaRepository 在 Spring Data JPA 中使用“TRUNCATE”?还是比标准 deleteAll() 更有效的方法?

Posted

技术标签:

【中文标题】是否可以使用 JpaRepository 在 Spring Data JPA 中使用“TRUNCATE”?还是比标准 deleteAll() 更有效的方法?【英文标题】:Is it possible to use "TRUNCATE" in Spring Data JPA using JpaRepository? Or a more effective method than the standard deleteAll()? 【发布时间】:2019-03-30 01:22:56 【问题描述】:

我目前使用标准的 jparepository 方法 repository.deleteAll() 在添加新信息之前清理我的表。该表由 8300 行组成,每行 5 列。目前将它们全部删除大约需要 80 秒,而使用标准 repository.saveAll(list) 将它们放入需要 1-3 秒。有没有更有效的方法来做到这一点?使用 DELETE FROM 表在 sql 中手动删除数据需要 0.1 秒。使用 mysql 数据库。 log from putting in data log from deletion.

【问题讨论】:

备注:DELETE FROM tTRUNCATE t 有区别:自增编号。 请注意发布的答案。您可以将其用作本机查询,返回 void,但您也可以将返回作为 Page 并返回预期的零计数(但您还需要在 @Query 中添加 countQuery) 【参考方案1】:

deleteAll 正在获取所有实体,然后一一删除:

// Code from SimpleJpaRepository

@Transactional
public void deleteAll() 

    for (T element : findAll()) 
        delete(element);
    

我建议您在 repo 中创建自己的删除方法,例如:

@Modifying
@Transactional
@Query("delete from MyEntity m")
void deleteAllWithQuery();

这将只创建一个 SQL DELETE 语句。

【讨论】:

感谢您的解释,帮助了我。 DELETE 是 DML 命令,TRUNCATE 是 DDL 命令。因此,TRUNCATE TABLE 比 DELETE 更快并且使用更少的系统资源,因为 DELETE 会扫描表以生成受影响的行数,然后逐一删除这些行并在数据库日志中为每个删除的行记录一个条目,而 TRUNCATE TABLE 只是删除所有行而不提供任何其他信息。 这比上面答案中提到的使用截断更快吗? 截断更快,但删除不会被写入日志,也许有人需要【参考方案2】:

例如,在您的服务接口中:

public interface MyTableInterface 
    //...

    void truncateMyTable();

在您的服务实现中(使用@AutowiredmyTableRepository):

public class MyTableImpl implements MyTableService 

    // other methods, @Autowiring, etc

    @Override
    @Transactional
    public void truncateMyTable() 
        myTableRepository.truncateMyTable();
    

在您的存储库中;

public interface MyTableRepository extends JpaRepository<MyTable, Long> 
    //....

    @Modifying
    @Query(
            value = "truncate table myTable",
            nativeQuery = true
    )
    void truncateMyTable();

编辑:还要注意服务实现层上的@Transactional,而不是把它放在DAO/Repository层上

【讨论】:

这行得通,缩短到 1 秒。感谢您的快速回复! 迄今为止的最佳答案 请记住,TRUNCATE 是 DDL 而不是 DML。通常,应用程序不应具有发出 DDL 命令的权限。 请注意,此查询仅适用于修改注释。我认为不需要它并尝试使用它,但我一直收到错误消息。不知道为什么需要它,也许其他一些答案有这些信息。如果我能找到任何信息,我会更新,但仍然需要它,否则 hibernate 会抱怨。

以上是关于是否可以使用 JpaRepository 在 Spring Data JPA 中使用“TRUNCATE”?还是比标准 deleteAll() 更有效的方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring 中将 OrderBy 与 JPARepository 一起使用

我可以在 JpaRepository nativeQuery 中使用枚举参数吗?

如何制作没有类型的 JpaRepository,或者只制作查询的 jpa repo?

是否可以在 Sql Server 中使用整数数组参数创建 sp? [复制]

是否可以使用 sp_executesql 创建视图?

70 JpaRepository 查询方法没有实现却可以正常使用