执行-结果-呼-在休眠-得到-总数的-行 问题触发另一个问题对我来说,有关 一些执行情况的关注:

现在你知道你必须再利用的部分非常查询的做计数、如何重用有效?

两者之间的差异非常查询:

  1. 选择是 count(?), ,而不是只或财产(或列表的)
  2. 的获取不应该发生,因此,一些表不应该加入
  3. order by 应该消失

是否还有其他的差异?

你有没有 编码的最佳做法来实现这一重用有效 (关切的问题:努力、清晰度、性能)?

例如,为一个非常简单的查询:

    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

更新

我收到答案:

  • 使用 标准 (但是我们使用非常大多)
  • 操纵字符串 查询(但每个人都同意这看起来复杂和不安全)
  • 包装的查询, 依靠数据库的优化(但是有一种感觉,这是不安全)

我希望有人会得到选择另一条道路,更多的关于字符串连接。
我们可以建立两个非常查询使用共同的部分?

有帮助吗?

解决方案

好的问题。这是我做了什么,在过去的(许多事情你已经提到):

  1. 检查是否 选择 条款是存在的。
    1. 如果不是的话,请加 select count(*)
    2. 否则检查它是否有 不同的 或集合体的功能。如果你使用这些代码分析你的查询,这是可能的工作围绕这些,但这是相当参与。你很可能会更好,只是包装的整个事情 select count(*) from ().
  2. 删除 fetch all properties
  3. 删除 fetch 从加入如果你分析非常as string.如果你真的分析查询与这些代码,你可以除去 left join 完全;这是相当混乱,以检查所有可能的参考文献。
  4. 删除 order by
  5. 根据你做了什么在1.2你会需要删除/调整 group by / having.

上述适用于非常、自然。对标准的查询,你很有限,与你可以做些什么,因为它不适合操纵容易。如果您使用的是某种形式的包层之上的条件,你会有同等的(有限)的子集这些代码分析结果和可适用上述大多数在这种情况。

因为你通常会举行,抵消当前页的总数,我通常运行实际查询与给予限制/抵消的第一和唯一运行的 count(*) 如果查询结果数量返回是多于或等于限制和偏移是零(在所有其他情况下我们运行的 count(*) 之前我已经得到了所有的结果无论如何)。这是一个乐观的方法方面的并行修改,课程。

更新 (手工装配非常)

我特别不喜欢这种做法。当映为名查询,非常具有优势的建立时的错误检查(良好,运行时间从技术上讲,因为它已经建成,尽管这通常是在一体化测试无论如何)。当在运行时生成的,它未能在运行时:-)做性能优化不是容易的。

同样的推理适用于标准,当然,但它是一个有点难搞砸了由于定义API相对于字符串连接。建立两个非常查询的并行(一页和"全球数"之一)也导致重复代码(而且可能更bug)或者迫使你写信有些种类的包装上的层顶到为你做它。这两种方法是远远不够理想。如果你需要做到这一点从客户代码(如在过API),该问题变得甚至更糟。

我实际上 思考一点 在这个问题。搜索API 休眠一般性道 似乎是一个合理的妥协;有更多的详细信息在我的回答上述联系的问题。

其他提示

你有没有尝试过让你意图明确的休眠通过设置一个投射在你的(SQL?)标准是什么?我大多已使用的标准,所以我不知道该如何适用于这是您的情况,但我已经被使用

getSession().createCriteria(persistentClass).
setProjection(Projections.rowCount()).uniqueResult()

让休眠图使用缓存/重复使用/智慧的东西本身..不真的知道有多少智慧的东西,它实际上,虽然..任何人都关心在评论这个吗?

嗯,我不知道这是一个最佳实践,但是我的实践:)

如果我有查询是这样的:

select A.f1,A.f2,A.f3 from A, B where A.f2=B.f2 order by A.f1, B.f3

我只是想知道有多少结果将得到我执行:

select count(*) from ( select A.f1, ... order by A.f1, B.f3 )

然后得到的结果作为一个整数,而不映射的结果,在一个组成。

分析你的查询,为删除的一些部分,如'了受'是非常复杂。一个良好的关系型数据库将优化您的查询对你。

好的问题。

在一个徒手非常情况我会用这样的事情,但这是不可重复使用,因为它是相当特定的实体

Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();

这样做一次调整的起始数,因此直到你网页通过。

对于标准虽然我用一样喜欢这个

final Criteria criteria = session.createCriteria(clazz);  
            List<Criterion> restrictions = factory.assemble(command.getFilter());
            for (Criterion restriction : restrictions)
                criteria.add(restriction);
            criteria.add(Restrictions.conjunction());
            if(this.projections != null)
                criteria.setProjection(factory.loadProjections(this.projections));
            criteria.addOrder(command.getDir().equals("ASC")?Order.asc(command.getSort()):Order.desc(command.getSort()));
            ScrollableResults scrollable = criteria.scroll(ScrollMode.SCROLL_INSENSITIVE);
            if(scrollable.last()){//returns true if there is a resultset
                genericDTO.setTotalCount(scrollable.getRowNumber() + 1);
                criteria.setFirstResult(command.getStart())
                        .setMaxResults(command.getLimit());
                genericDTO.setLineItems(Collections.unmodifiableList(criteria.list()));
            }
            scrollable.close();
            return genericDTO;

但是,这并的计算每一时间通过调用 ScrollableResults:last().

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top