2009-07-07 24 views
1

我正在將遺留的iBatis實現轉換爲Hibernate,並且爲了向後兼容,需要顯示對象集合的計數而不是集合本身。原始查詢是:如何在Hibernate中實現這個查詢?

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

和b_count將出現在響應中。我希望能夠做到這一點,而不需要爲每個查詢結果延遲加載A的B集合。

任何想法或建議嗎?

+0

我辦公室的一位同事推薦了@Formula註釋。我會把這個決議寫成答案。 – 2009-07-08 13:24:22

回答

2

最好的方法似乎是使用Hibernate的公式,映射到我的BCount的getter和setter在A級屬性我的代碼:

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; 
    } 
} 

有關該方法的好處是,計數在相同的獲取返回來滋潤初始對象,而不會導致1個+ N次查詢的集合查詢resul TS!

+0

我甚至不知道這是可能的。我知道我的代碼庫中有幾個地方會從中受益。 – Jesse 2009-07-10 12:26:24

0

您可以使用投影。

的行數的語法如下:

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

編輯:重新閱讀後,我覺得這可能不是你問什麼....

+0

這不是我正在尋找,但它仍然感激! – 2009-07-07 20:52:10

0

Hibernate的過濾器用於對查詢結果應用附加限制(例如,將它們視爲「where」條款的一部分),因此它們不會按照您的要求進行操作。你這裏有兩種選擇:

A)你可以急切地得到B的集合爲您答:

from A a left join fetch a.Bs b
如果這樣做,請記住,對於查詢將返回多個正如你可以在結果得到重複列表(例如,如果您有2個,每個都有3個B,您將得到6個結果)。將它們包裹在一套中以確保獨特性。

B)假設你有一個合適的構造函數,你可以做到以下幾點:

 
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