我正在將遺留的iBatis實現轉換爲Hibernate,並且爲了向後兼容,需要顯示對象集合的計數而不是集合本身。原始查詢是:如何在Hibernate中實現這個查詢?
select A.*, (select count(*) from B where B.A_id = A.id) as B_count from A;
和b_count將出現在響應中。我希望能夠做到這一點,而不需要爲每個查詢結果延遲加載A的B集合。
任何想法或建議嗎?
我正在將遺留的iBatis實現轉換爲Hibernate,並且爲了向後兼容,需要顯示對象集合的計數而不是集合本身。原始查詢是:如何在Hibernate中實現這個查詢?
select A.*, (select count(*) from B where B.A_id = A.id) as B_count from A;
和b_count將出現在響應中。我希望能夠做到這一點,而不需要爲每個查詢結果延遲加載A的B集合。
任何想法或建議嗎?
最好的方法似乎是使用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!
我甚至不知道這是可能的。我知道我的代碼庫中有幾個地方會從中受益。 – Jesse 2009-07-10 12:26:24
您可以使用投影。
的行數的語法如下:
Criteria crit = session.createCriteria(B.class);
crit.setProjection(Projections.rowCount());
List results = crit.list();
編輯:重新閱讀後,我覺得這可能不是你問什麼....
這不是我正在尋找,但它仍然感激! – 2009-07-07 20:52:10
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
我辦公室的一位同事推薦了@Formula註釋。我會把這個決議寫成答案。 – 2009-07-08 13:24:22