2

我们大部分时间都在使用 HQL。但是我们有这个包含许多连接的复杂搜索表单,所以我想我会尝试使用 Criteria 的运气(以前从未有过)。我更喜欢这种语法,它适合我们拥有的复杂形式。

我的第一个直觉是在应用and.list().size()之前先做一个。这当然是缓慢而懒惰的,而且是一个总的资源消耗。setMaxResultssetFirstResult

经过一番谷歌搜索后,我找到了一个使用 ScrollableResults 的示例。但是帖子说 MySQL 不支持游标。这是 2004 年的一篇文章。在 2012 年,我们使用 MySQL 5 和 InnoDB 表。所以我认为我们支持游标。然后我发现使用投影。

所以不是休眠大师,我迷失了最好的方式。我们将来可能会使用 DB2,所以我想我使用的任何解决方案都必须在 DB2 和 MySQL 5 中工作。

有任何想法吗?我想至少我可以使用自定义 HQL 来获取计数(*)。

谢谢

更新

我只是把这个放在:

ScrollableResults scr = crit.scroll();
scr.last();
int rowCount = scr.getRowNumber() + 1;

对比

int rowCount = crit.list().size();

在我输入限制/起始值之前。它跑得更快。所以我假设游标适用于特定的数据库和结果。我什至在那里加入了一些连接,它似乎仍然要快得多。

关于这是否仍然是一个好主意的任何意见?

4

4 回答 4

2

您可以使用 Criteria 的setProjection(Projections.property("id")).

于 2012-11-09T20:03:11.217 回答
1

我认为通过单独的查询来获得计数是唯一的选择,如果你想通过使用setFirstResultand来应用分页setMaxResults

于 2012-11-09T16:19:50.753 回答
0

肯定crit.list().size()会在 Hibernate 会话中加载完整的行集作为实体。

该方法ScrollableResults.last()取决于 JDBC 驱动程序的实现,它也可能非常慢,因为ResultSet可能会完全加载完整的内容,即使尚未创建 Hibernate 实体也是如此。

最好的选择是使用crit.setProjection(Projections.rowCount()).uniqueResult()

于 2014-04-11T06:19:01.000 回答
0

你可以hashcode()在你的代码中包含,也就是说,

criteria.setProjection(Projections.rowCount()).uniqueResult().hashCode()
于 2014-10-01T08:26:39.363 回答