Hibernate和删除全部数据

38

什么是在Hibernate中删除表中所有行的最佳方法?

如果我遍历集合并调用session.delete(),据我所知它并没有执行。

如果我使用另一种选项session.createQuery("delete ..."),它不会影响持久化上下文。

如果没有更好的选择,我应该在什么时候使用这些方法?

3个回答

28

你可以使用HQL来截断表

public int hqlTruncate(String myTable){
    String hql = String.format("delete from %s",myTable);
    Query query = session.createQuery(hql)
    return query.executeUpdate();
}

这是最好的方法。 - Shervin Asgari
10
查询时需要写Java类文件的名称,而不是表格(table)的名称。 - Muhammad Imran Tariq
4
不进行级联删除,因此可能违反外键约束。 - atamanroman
5
这不是一个截断。 - Steve Swinsburg

27
  • 如果没有需要级联的内容,请使用HQL delete DELETE FROM enityName
  • 如果存在级联关系,请逐个迭代集合并单独删除。

问题在于Hibernate内部处理级联关系,而不是将其留给数据库。因此,发送查询不会触发内部级联,因此您将拥有不一致/孤儿数据。

如果性能非常重要(毕竟不是每天都要截断表),那么可以为每个级联关系使用多个HQL delete - 即手动处理级联关系。


10
String stringQuery = "DELETE FROM tablename";
Query query = session.createQuery(stringQuery);
query.executeUpdate();

为什么使用createQuery比迭代集合并调用session.delete()更好?我会遇到持久化上下文的问题吗? - feiroox
3
更好的方法是,当你遍历集合并调用删除操作时,它将按行逐个删除。这是一个很大的性能问题。然而,正如Bozho所说,如果你有级联操作,你可能会希望这样做。 - Shervin Asgari
1
如上所述,这个程序并不处理级联。我不知道是否有可能更强调一下这一点。我曾经浪费了很多时间,因为我认为运行HQL会处理级联。毕竟它是Hibernate查询语言。但是,可悲的是,它并不会。你必须使用session.delete(),但这会为每个单独的记录发出一个SQL语句,非常低效。 - Jack Holt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接