hibernate是否支持count(*)over()

我试图阻止必须为count创建一个单独的查询,为实际查询创建一个查询。 我发现SesssionImpl :: createQuery需要相当长的时间来进行复杂的查询,通过组合count和主查询,我可以消除一个createQuery调用。

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

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

这可以在hibernate中实现吗?

(我试图避免使用本机sql并坚持使用HQL和分离标准。使用本机SQL会破坏使用hibernate的目的。我的系统必须同时支持Oracle和Sybase)

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(*) .over ()}". */ static String cleanCountOver(String sql) { return sql.replaceAll("(?i) (count)\\(\\*\\) \\w+\\.(over) \\(\\)", " $1(*) $2 () "); } } 

除了明确的Hibernate依赖(而不是纯JPA)之外,还有另一个缺点,即默认情况下将加载此列,这可能会为不需要计数的查询添加一些不必要的开销。 有可能使列可选并且延迟加载 ,但这需要字节码检测并增加了更复杂的层。

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

您可以将此用于: –

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