對于一個已經(jīng)加載的Customer對象,假設對它的orders集合采用延遲加載機制,那么當調(diào)用customer.getOrders().iterator()時,Hibernate就會初始化orders集合,然后到數(shù)據(jù)庫中去加載Customer對象所關(guān)聯(lián)的Order對象,并且填充orders集合,但是很多時候我們其實只是需要關(guān)聯(lián)對象中符合某些條件的一部分對象,而并不需要加載全部關(guān)聯(lián)對象,而對性能帶來無謂的開銷。這時候我們就可以利用Hibernate的集合過濾功能,來處理關(guān)聯(lián)對象的加載。我們看下面的代碼:
List list=session.createFilter(customer.getOrders(),“where this.price>100 order by this.price”).list();
for(int i=0;i<list.size();i++){
Order order=(Order)list.get(i);
}
在上面代碼中通過session.createFilter()方法,創(chuàng)建了一個集合過濾的查詢對象,這個方法需要兩個參數(shù),第一個參數(shù)指定需要進行過濾操作的集合,第二個參數(shù)指定過濾集合的條件,方法返回Query對象。這個方法不要求它所要操作的集合對象已經(jīng)初始化,但是要求包含這個集合對象的實體對象必須處于持久化狀態(tài)。當執(zhí)行list()方法時不管持久化對象的集合是否已經(jīng)初始化,都會到數(shù)據(jù)庫中去檢索數(shù)據(jù),為了保證在Hibernate緩存中不會出現(xiàn)OID相同的對象,如果集合對象已經(jīng)初始化,list()方法不會創(chuàng)建新的關(guān)聯(lián)實體對象,而僅僅返回已經(jīng)存在的關(guān)聯(lián)實體對象。如果集合對象還沒有初始化,那么list()方法會創(chuàng)建關(guān)聯(lián)實體對象,但是不會初始化容納關(guān)聯(lián)實體對象的集合。除了可以向集合對象添加過濾條件進行稽核過濾之外,還可以進行很多其他操作,看下面的代碼:
① 、對集合對象進行分頁:
List list=session.createFilter(customer.getOders(),”order by this.price asc”)
.setFirstResult(10)
.setMaxResults(50)
.list();
②、檢索集合中關(guān)聯(lián)對象的一個屬性:
List list=session.createFilter(customer.getOrders(),”select this.ordernumber ”).list();
2、子查詢:
子查詢是SQL語句中非常重要的功能特性,它可以在SQL語句中利用另外一條SQL語句的查詢結(jié)果,在Hibernate中HQL查詢同樣對子查詢功能提供了支持。如下面代碼所示:
List list=session.createQuery(“from Customer c where 1>(select count(o) from c.orders o)”).list();
上面的程序查詢訂單數(shù)超過1的所有客戶,因此和上面子查詢HQL語句對應的SQL語句為:
Select * from Customer c where 1>(select count(o.id) from Order o where c.id=o.customer_ID);
如果子查詢返回多條記錄,則可以使用下面關(guān)鍵字:
all:表示子查詢語句返回的所有記錄
any:表示子查詢語句返回的任意一條結(jié)果
some:與”any”等價
in:與”=any”等價
exists:表示子查詢語句至少返回一條記錄
例如:查詢存在一條訂單價格大于100的客戶
From Customer c where 100>any(select o.price from c.orders o);
如果在子查詢中操作集合,HQL提供了一組操縱集合的函數(shù)和屬性:
size()函數(shù)和size屬性:獲得集合中元素的數(shù)量
minIndex()函數(shù)和minIndex屬性:對于建立了索引的集合獲得最小索引值(關(guān)于集合索引參考第一部分映射值類型集合)
minElement()函數(shù)和minElement屬性:對于包含基本類型的元素集合,獲得集合中值最小的元素
maxElement()函數(shù)和maxElement屬性:對于包含基本類型元素的集合,獲得集合中值最大的元素
element()函數(shù):獲得集合中所有元素
例如:查詢訂單數(shù)大于0的客戶
From Customer c where size(c.orders)>0;或者From Customer c where c.orders.size>0;
以上HQL語句會生成類似如下的SQL語句:
Select * from customer c where 0>(select count(o.id) from order where o. customer_ID =c.id);
注:在HQL中子查詢必須出現(xiàn)在where子句中,而且必須用一對圓括號括起來。為什么必須要出現(xiàn)在where字句之后呢?其實我們大家仔細想一下也就知道了,在Hibernate中查詢的任何一個實體對象都要有據(jù)可循,這個“據(jù)”就是Hibernate的主配置文件,也就是說凡是出現(xiàn)在HQL from字句中的實體對象,都必須要在Hibernate主配置文件中有明確的配置。所以在Hibernate中無法支持SQL語句中的那種出現(xiàn)在from字句之后的那種動態(tài)視圖子查詢。