查詢方式: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對象的創建依賴於session,在線的話就是用session將criteria創建,離線的話就是憑空將criteria創建,
在線:
離線:
懶加載|延遲加載
load方法:應用類級別的加載策略,可以在對象配置文件中進行配置,默認策略是延遲加載,是在執行時不發送任何sql語句,返回一個對象,使用該對象時,根據關聯的session查詢數據庫,加載數據。
get方法不能配置,只有一種立即加載策略。
延遲加載:僅僅獲得沒有使用,不會查詢。在使用時才進行查詢。
是否對類進行延遲加載:可以通過在class元素上配置lazy屬性來控制。
lazy:true 加載時 不查詢,使用時才查詢
lazy:false 加載時立即查詢
在debug中看到代理對象的值出現$符號時,表明它是一個代理對象。可以讓代理customer對象有查詢數據庫的功能,當需要使用時,便查詢數據。
shi
以前在中文符號的問題那裏進行過代理,轉換過request,以便適應中文,在數據庫中進行過代理,以實現連接池。
結論:爲了提高效率,建議使用load加載即延遲加載策略。
注意:使用懶加載時要確保,調用屬性加載數據時,session還是打開的,不然會拋出異常。
關聯級別延遲加載&抓取策略
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。
利用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的問題爲什麼不會在這裏在出現。