在实施对结果分页功能于hibernate,让计用户号码的,行的问题触发另一个问题对我来说,对 一些执行情况表示关注 :
现在您知道必须重用HQL查询的一部分来进行计数,如何有效地重用?
两个HQL查询之间的区别是:
count(?)
order by
还有其他区别吗?
您是否有 编码最佳实践来有效地实现这种重用 (问题:努力,清晰,性能)?
一个简单的HQL查询示例:
select a from A a join fetch a.b b where a.id=66 order by a.name select count(a.id) from A a where a.id=66
更新
我收到以下答案:
我希望有人会沿着另一条路径提供更多选项,这些路径与String串联更多相关。 我们可以使用公共部分来构建两个HQL查询 吗?
好问题。这是我过去所做的(您已经提到的许多事情):
select count(*)
select count(*) from ()
fetch all properties
fetch
left join
group by
having
以上自然适用于HQL。对于Criteria查询,您只能做些限制,因为它不便于操作。如果您在Criteria之上使用某种包装层,则最终将得到ANTLR解析结果的(有限)子集,并且在这种情况下可以应用上面的大多数内容。
由于您通常会保留当前页面的偏移量和总计数,因此我通常会先使用给定的限制/偏移量运行实际查询,并且仅在count(*)返回的结果数大于或等于限制且偏移量为零时才运行查询(在所有其他情况下,我要么count(*)之前运行过,要么无论如何都要获得所有结果)。当然,对于并发修改,这是一种乐观的方法。
count(*)
更新 (手工组装HQL)
我不太喜欢这种方法。当映射为命名查询时,HQL具有构建时错误检查的优势(从技术上来说,运行时是因为必须构建SessionFactory,尽管无论如何这通常是在集成测试中完成的)。当在运行时生成时,它会在运行时失败:-)进行性能优化也不是一件容易的事。
当然,同样的推理也适用于Criteria,但是由于定义良好的API(而不是字符串连接),因此更难解决。并行构建两个HQL查询(分页为一个,“全局计数”为一个)也会导致代码重复(并可能有更多的错误),或者迫使您在顶部编写某种包装层来为您完成。两种方法都不理想。而且,如果您需要从客户端代码执行此操作(如通过API进行操作),问题将变得更加严重。
实际上,我在这个问题上已经考虑了很多。Hibernate-Generic- DAO的 Search API 似乎是一个合理的折衷方案。我对上述链接问题的回答中有更多详细信息。