【问题标题】:Does hibernate support count(*) over()hibernate 是否支持 count(*) over()
【发布时间】:2014-03-04 05:05:32
【问题描述】:

我试图避免为计数创建一个单独的查询,为实际查询创建一个。我发现 SesssionImpl::createQuery 需要花费大量时间来处理复杂查询,通过结合计数和主查询,我可以消除一次 createQuery 调用。

在 SQL 中我可以做类似的事情

select count(*) over(), col_A, col_B 
from TABLE_XX 
where col_C > 1000

这可以在hibernate中实现吗?

(我试图避免使用原生 sql 并坚持 HQL 和分离标准。使用原生 SQL 违背了使用休眠的目的。我的系统必须同时支持 Oracle 和 Sybase)

【问题讨论】:

  • 嗯,你总是可以使用本机 sql。我假设你想避免这种情况?
  • 是的,我试图避免使用原生 sql 并坚持 HQL 和分离的标准。使用原生 SQL 违背了使用 hibernate 的目的。
  • 你的底层数据库是什么?
  • 我的系统必须同时支持 Oracle 和 Sybase
  • 简单地使用本地 SQL 带或不带休眠。分析函数是标准的,大多数现代 RDBMS 实现都支持它们。实际上,使用纯 SQL 而不是“面向对象的查询”总是更好,因为它们在工具之间更具可移植性,易于测试,不会产生混淆,而且速度更快。

标签: java sql hibernate window-functions


【解决方案1】:

Hibernate 的@Formula 注释可以作为一种解决方法。在您的 @Entity 中提供一个额外的列来表示计数,并用 @Formula 注释,其中包含 COUNT OVER 查询:

@Formula("count(*) over ()")
private Integer totalResults;

不过,通过这种方法,Hibernate 会对生成的 SQL 产生一点影响,因此您可能还需要注册一个 Interceptor 来清理 SQL:

public class CountOverQueryInterceptor extends EmptyInterceptor {

    private static final long serialVersionUID = -2980622815729060717L;

    @Override
    public String onPrepareStatement(String sql) {
        return super.onPrepareStatement(cleanCountOver(sql));
    }

    /**
     * Cleans the "{@code count(*) over ()}" query fragment from Hibernate's sql
     * decoration "{@code count(*) <alias>.over ()}".
     */
    static String cleanCountOver(String sql) {
        return sql.replaceAll("(?i) (count)\\(\\*\\) \\w+\\.(over) \\(\\)", " $1(*) $2 () ");
    }

}

除了显式的 Hibernate 依赖项(而不是纯 JPA)之外,还有另一个缺点,即默认情况下会加载此列,这可能会给不需要计数的查询增加一些不必要的开销。可以将列设为可选和lazily loaded,但这需要字节码检测并进一步增加复杂性。

@Formula("count(*) over ()")
@Basic(optional = true, fetch = FetchType.LAZY)
private Integer totalResults;

【讨论】:

    【解决方案2】:

    您可以将其用于:-

    return (Number) session.createCriteria("Book").setProjection(Projections.rowCount()).uniqueResult();
    

    【讨论】:

      猜你喜欢
      • 2018-02-28
      • 2014-09-05
      • 2013-08-20
      • 2017-03-11
      • 1970-01-01
      • 2011-04-24
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多