【问题标题】:Hibernate Criteria API - HAVING clause work aroundsHibernate Criteria API - HAVING 子句变通方法
【发布时间】:2010-10-02 19:16:25
【问题描述】:

我使用 Hibernate Criteria API 编写了一个查询来获取特定值的总和,现在我需要能够将结果限制为总和大于或等于特定值的行。

通常我会在我的 SQL 中使用 HAVING 子句来执行此操作,但 Criteria API 目前似乎不支持该功能。

在原始 SQL 中,这是我需要做的:

SELECT user_pk, sum(amount) as amountSum
FROM transaction
GROUP BY user_pk
HAVING amountSum >=50;

我想到的一种解决方法是在 FROM 子句中使用一个子查询来获取这个总和值,并使用一个外部查询来使用 WHERE 子句来限制它。

因此,在原始 SQL 中,它看起来像:

SELECT user_pk, amountSum
FROM (SELECT user_pk, sum(amount) as amountSum
      FROM transaction
      GROUP BY user_pk)
WHERE amountSum > 50;

谁能指出我如何使用 Criteria API 编写此代码的正确方向,或者我可以用来解决 HAVING 问题的任何其他建议/解决方法?

这是我用于上述示例的 Criteria API 代码

DetachedCriteria criteria = DetachedCriteria.forClass(Transaction.class,"transaction");
criteria.setProjection(criteria.setProjection(Projections.projectionList().add(
        Projections.groupProperty("user.userPK").as("user_pk")).add(
            Projections.sum("transaction.amount").as("amountSum")));

谢谢!

【问题讨论】:

    标签: hibernate criteria having


    【解决方案1】:

    HHH-1700 被标记为 HHH-1043 的副本,因此不会被修复。您可以在 HHH-1043 上找到我以及其他人的解决方案和解决方法。

    【讨论】:

    • 这是 7 年前的事了,仍然没有在 hibernate 中打补丁,我需要为 4.3.6 或更高版本应用补丁,但是代码已经改变了很多,我不清楚该怎么做它。有人更新了这个补丁吗?
    【解决方案2】:
    【解决方案3】:

    我不知道 Hibernate/NHibernate 在 FROM 子句中使用子查询的方法,但您可以在 WHERE 子句中使用它们。 对于任何 Java/Hibernate 代码错误,我深表歉意,我更熟悉 C#/NHibernate。

    DetachedCriteria subQuery = DetachedCriteria.forClass(Transaction.class); subQuery.setProjection(Projections.sum("amount")); subQuery.add(Expression.eqProperty("userPk", "tOuter.userPk")); DetachedCriteria outerQuery = DetachedCriteria.forClass(Transaction.class, "tOuter"); outerQuery.setProjection(Projections.projectionList() .Add(Projections.sum("amount").as("sumAmount")) .Add(Projections.groupProperty("userPk").as("user_pk")); outerQuery.add(Subqueries.le(50, subQuery));

    此代码应产生类似于以下内容的 SQL:

    SELECT tOuter.userPk as user_pk, sum(tOuter.amount) as sumAmount FROM transaction tOuter WHERE 50 <= (SELECT sum(amount) FROM transaction WHERE userPk = tOuter.userPk) GROUP BY tOuter.userPk

    这种方法的缺点是它计算每个总和两次,这可能会对性能产生不利影响,具体取决于所涉及的数据量 - 在这种情况下,您将需要使用支持 HAVING 的 HQL 查询子句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-24
      • 2011-02-17
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 2019-04-01
      • 2017-01-20
      • 2021-05-15
      相关资源
      最近更新 更多