Hibernate框架入門(四)

                                      第一章 查詢-HQL語法

查詢方式:oid查詢-get、對象屬性導航查詢、HQL、Criteria、原生SQL

HQL基本檢索

排序:

條件:

  分頁:

從零條開始查,每頁兩條

統計:

count、sum、avg、max、min

如果是單個查詢的話,建議不用list,用uniqueResult比較好,count的查詢結果爲Long型。

投影查詢:投影只能投影一部分,其實也就是隻查詢屬性中的一部分內容。

如:

 

多表查詢:

回顧原生sql

交叉連接-笛卡兒積(避免)

select * from A,B

內連接(隱式內連接,顯式內連接)

隱式:select * from A,B where b.ais=a.id

顯式:select * from A inner join B on b.aid = a.ad

外連接左外,右外

左外:select * from A left [outer] join B on b.aid = a.id

右外:select * from B left[outer] join B on b.aid = a.id

HQL 的多表查詢

內連接:下面的hql語句表示給customer起別名c,並自己連接自己的屬性,最終會在內部轉換熟悉的sql語句,將可以連接的進行連接,將連接的兩端對象進行返回。

迫切內連接:迫切是封裝後給你,將連接的對象裝入customer的LinkMen的集合中。

外連接:

左外連接:

右外連接:

 

                                   第二章 查詢-Criteria語法

無語句面對對象的查詢

基本查詢:

條件查詢:

更多的條件見表:

分頁查詢:

排序:                      

統計:

離線查詢:Criteria對象的創建依賴於session,在線的話就是用session將criteria創建,離線的話就是憑空將criteria創建,

在線:

 

離線:

 

                                      第三章 查詢策略優化

3.1 類級別查詢

懶加載|延遲加載

load方法:應用類級別的加載策略,可以在對象配置文件中進行配置,默認策略是延遲加載,是在執行時不發送任何sql語句,返回一個對象,使用該對象時,根據關聯的session查詢數據庫,加載數據。

get方法不能配置,只有一種立即加載策略。

延遲加載:僅僅獲得沒有使用,不會查詢。在使用時才進行查詢。

是否對類進行延遲加載:可以通過在class元素上配置lazy屬性來控制。

lazy:true 加載時 不查詢,使用時才查詢

lazy:false 加載時立即查詢

在debug中看到代理對象的值出現$符號時,表明它是一個代理對象。可以讓代理customer對象有查詢數據庫的功能,當需要使用時,便查詢數據。

shi

以前在中文符號的問題那裏進行過代理,轉換過request,以便適應中文,在數據庫中進行過代理,以實現連接池。

結論:爲了提高效率,建議使用load加載即延遲加載策略。

注意:使用懶加載時要確保,調用屬性加載數據時,session還是打開的,不然會拋出異常。

3.2 關聯級別查詢

關聯級別延遲加載&抓取策略

3.21 集合關聯策略

lazy屬性:決定是否延遲加載 true:延遲加載, false:立即加載 extra:極其懶惰

fetch屬性:決定加載策略。使用什麼類型的sql語句加載集合數據

select:單表查詢加載

join:使用多表查詢加載集合

subselect:使用子查詢加載集合

依次對這個屬性進行排列組合,進行不同的測試。

爲了敘述的方便,將下圖中代碼按照第一行,第二行,第三行等等進行描述。

(1) fetch:select     lazy:true   (默認值)

用單表查詢,第一行執行時單表查詢加載customer,第二行不查詢linkmen,第三行需要用的時候再加載linkmen。

(2)  fetch:select     lazy:false

再第一行將所有數據全部加載。

(3) fetch:select     lazy:extra(極其懶惰)

第一行執行時單表查詢加載customer,第二行不查詢linkmen,第三行只查詢行數,不加載linkmen,第三行需要用的時候再加載linkmen。

(4) fetch:join     lazy:true

因爲是多表查詢,所以在第一行即將所有的數據查完,lazy是什麼也就失去了作用。

(4) fetch:subselect     lazy:true

只查詢一個表時沒機會用到子查詢的,當如下情況會用到子查詢。

第三行會查詢所有customer,第五行正常輸出,第六行會使用子查詢,將所有的linkmen查出來。

(5) fetch:subselect     lazy:false

 

 

在三行會加載所有customer並利用子查詢加載所有linkmen。

(6) fetch:subselect     lazy:true

第三行加載customer,第六行只查詢size,第七行根據子查詢查詢所有linkmen。

3.22 關聯屬性策略

利用linkmen反過來加載customer

配置:

 

 

fetch:select     lazy:proxy     customer:true

第一行只會加載linkmen,因爲懶加載,所以第三行使用時才加載customer。

fetch:select     lazy:proxy|false     customer:false

第一行會將linkmen以及它對應的customer全部加載

fetch:join     lazy:proxy

多表查詢就是無論如何都會查出與linkmen關聯的customer,所以lazy屬性就無所謂了。

結論:爲了提高效率,fetch的選擇應爲select,lazy的取值應選擇true,即都是默認值。

no-session問題:當開啓懶加載的時,若在web層中需要使用某對象的關聯集合或者屬性的話,因爲在service層中已將session關閉,這裏我們將不能找到需求的對象。

解決方法:擴大session的作用範圍,可以使用過濾器來解決問題,

                              第四章:爲客戶列表增加查詢操作

根據客戶名稱查詢對象

web層:

如要在web層添加條件,應使用離線查詢。

cust_name要加上百分號,不然變成了等於。

 

service層:

 

dao層:

 

將查詢條件回顯:

小疑問:session爲什麼不用打開了,之前說的no-session的問題爲什麼不會在這裏在出現。