如何在Hibernate中实现这个Query?

时间:2009-07-07 20:28:16

标签: java sql hibernate

我正在将遗留的iBatis实现转换为Hibernate,出于向后兼容的目的,需要提供对象集合的计数而不是集合本身。原始查询是:

select A.*, ( select count(*) from B where B.A_id = A.id ) as B_count from A;

和b_count将显示在回复中。我希望能够做同样的事情,而不会为每个查询结果延迟加载A的B集合。

有任何想法或建议吗?

3 个答案:

答案 0 :(得分:2)

最好的方法似乎是使用Hibernate公式,映射到A类中我的BCount属性的getter和setter。我的代码:

public class A {
   // ...
   private long bCount;

   // ...

   @Formula( "(select count(*) from B where B.A_id = id" )
   public long getBCount() {
      return this.bCount;
   } 

   public void setBCount( long bCount ) {
      this.bCount = bCount;
   }
}

关于这个方法的好处是,计数在同一个fetch中返回以包含初始对象,并且不会导致1 + N查询收集查询结果!

答案 1 :(得分:0)

您可以使用投影。

行计数的语法如下:

    Criteria crit = session.createCriteria(B.class);
    crit.setProjection(Projections.rowCount());
    List results = crit.list();

编辑:重新阅读后,我认为这可能不是你所要求的......

答案 2 :(得分:0)

Hibernate过滤器用于对查询结果应用其他限制(例如将它们视为“where”子句的一部分),因此它们不会执行您想要的操作。你有两个选择:

A)你可以急切地为你的A收集Bs:

from A a left join fetch a.Bs b
如果你这样做,请记住,对于会返回多个的查询,因为你可能会在结果列表中得到重复项(例如,如果你有2个As,并且每个都有3个B,那么你将得到6个结果)。将它们包裹在一套以确保独特性。

B)假设您有适当的A构造函数,您可以执行以下操作:

 select new A(a.field1, a.field2, ... a.fieldN, count(*) as B_count)
   from A a left join a.Bs b
  group by a.field1, a.field2, ... a.fieldN