当前位置: 首页 > 面试题库 >

重用查询的一部分进行计数的Java编码最佳实践

华宏逸
2023-03-14
问题内容

在实施对结果分页功能于hibernate,让计用户号码的,行的问题触发另一个问题对我来说,对
一些执行情况表示关注

现在您知道必须重用HQL查询的一部分来进行计数,如何有效地重用?

两个HQL查询之间的区别是:

  1. 选择是count(?),而不是pojo或属性(或列表)
  2. 提取不应发生,因此某些表不应联接
  3. 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

更新

我收到以下答案:

  • 使用 条件 (但我们主要使用HQL)
  • 处理String 查询(但每个人都同意这似乎很复杂,也不是很安全)
  • 包装查询 ,依靠数据库优化(但是有一种感觉,这是不安全的)

我希望有人会沿着另一条路径提供更多选项,这些路径与String串联更多相关。
我们可以使用公共部分来构建两个HQL查询 吗?


问题答案:

好问题。这是我过去所做的(您已经提到的许多事情):

  1. 检查是否存在 SELECT 子句。
    1. 如果不是,请添加 select count(*)
    2. 否则,请检查它是否具有 DISTINCT 或聚合函数。如果您正在使用ANTLR来解析查询,则可以解决这些问题,但是涉及很多。您最好将整个过程包装为select count(*) from ()
  2. 去掉 fetch all properties
  3. fetch如果要将HQL解析为字符串,请从联接中删除。如果您是使用ANTLR真正解析查询,则可以将其left join完全删除;检查所有可能的引用是很麻烦的。
  4. 去掉 order by
  5. 根据您在1.2中所做的事情,您需要删除/调整group by/ having

以上自然适用于HQL。对于Criteria查询,您只能做些限制,因为它不便于操作。如果您在Criteria之上使用某种包装层,则最终将得到ANTLR解析结果的(有限)子集,并且在这种情况下可以应用上面的大多数内容。

由于您通常会保留当前页面的偏移量和总计数,因此我通常会先使用给定的限制/偏移量运行实际查询,并且仅在count(*)返回的结果数大于或等于限制且偏移量为零时才运行查询(在所有其他情况下,我要么count(*)之前运行过,要么无论如何都要获得所有结果)。当然,对于并发修改,这是一种乐观的方法。

更新 (手工组装HQL)

我不太喜欢这种方法。当映射为命名查询时,HQL具有构建时错误检查的优势(从技术上来说,运行时是因为必须构建SessionFactory,尽管无论如何这通常是在集成测试中完成的)。当在运行时生成时,它会在运行时失败:-)进行性能优化也不是一件容易的事。

当然,同样的推理也适用于Criteria,但是由于定义良好的API(而不是字符串连接),因此更难解决。并行构建两个HQL查询(分页为一个,“全局计数”为一个)也会导致代码重复(并可能有更多的错误),或者迫使您在顶部编写某种包装层来为您完成。两种方法都不理想。而且,如果您需要从客户端代码执行此操作(如通过API进行操作),问题将变得更加严重。

实际上,我在这个问题上已经考虑了很多。Hibernate-Generic-
DAO的
Search API
似乎是一个合理的折衷方案。我对上述链接问题的回答中有更多详细信息。



 类似资料:
  • 问题描述 当前分页查询已经不局限于传统的通过用户单击页码栏实现分页 比如微博的首页就实现了滚动实时分页 所以出于好奇想问问大佬当前分页查询都有哪些成熟的实现方案,其各自的适用场景是什么

  • 我正在努力理解的行为。我想用它来编码查询参数中的URL,但它似乎只转义字符,而不转义其他必要的字符,如。 查询参数中根本没有编码的URL示例: 输出: 这是不正确的,因为未编码的会导致被解释为而不是的查询参数。 但是,如果使用包含字符的输入:: 输出: 字符被转义。 自动转义字符,但不转义其他保留字符,这似乎不一致。 使用将URL编码为查询参数的正确过程是什么?

  • 问题内容: 我最近为我在iOS中开发的iOS应用程序实现了AWS开发工具包。我已经连接到数据库实例并能够获得查询响应,但是,我正在努力将其转换为可用数据。我对Swift,AWS和编程一般还是比较陌生,因此可能缺少明显的东西! 我的代码如下: 控制台输出为: 对象:[{area =“ {\ n S = \” West Hampstead \“; \ n}”; name =“ {\ n S = \”

  • 我使用设置用户名的唯一约束,在将数据插入数据库之前检查重复值的最佳做法是什么? 通过捕获当您尝试插入具有相同用户名的数据时程序将引发的异常

  • 问题内容: 如何在Java中将查询参数编码为URL?我知道,这似乎是一个显而易见且已经提出的问题。 我不确定有两个微妙之处: 网址上的空格应该编码为“ +”还是“%20”?在chrome中,如果我输入“ http://google.com/foo=?bar me”,则chrome会将其更改为使用%20进行编码 是否有必要/正确将冒号“:”编码为%3B?Chrome没有。 笔记: 似乎不起作用,似乎

  • 在Java中,如何对url上的查询参数进行编码?我知道,这似乎是一个显而易见的问题。 有两个微妙之处我不确定: URL上的空格应该编码为"或"吗?在chrome中,如果我输入“http://google.com/foo=?bar我”chrome将其更改为编码 是否有必要/正确地将冒号":"编码为;?Chrome没有。 注意事项: 似乎不起作用,它似乎是用于编码要提交表单的数据。例如,它将空格编码为