學習筆記 Hibernate HQL進階

Hibernate HQL進階 
  
  HQL查詢優化
  在使用HQL 時 避免使用
   OR  not  like having distinct 等關鍵詞
    
數據加載方式 
當即加載
 特色:
Lazy ='true'
優勢:
對應用程序透明,無論對象處於什麼狀態  例如 持久態 ,遊離態  方便一個對象指引關聯對象的使用。
缺點:
session 語句使用頻繁不須要訪問對象形成內存空間浪費。
延遲加載
 特色:
Lazy = 'false'
優勢:與上面相反。。。。。。。。。。。。
延遲加載有三種
1: 集合類型的延遲加載。 <set lazy='true'> </set>
2: 實體對象加載     <class lazy='true'></class>
3: 屬性加載  
List() 方法 Iterate() 方法 
load()方法
          在使用了二級緩存的狀況下,使用load()方法會在二級緩存中查找指定的對象是否存在。
在執行load()方法時,Hibernate首先從當前Session的一級緩存中獲取ID對應的值,在獲取不到的狀況下,將根據該對象是否配置了二級緩存來作相應的處理。
如配置了二級緩存,則從二級緩存中獲取ID對應的值,如仍然獲取不到則還須要根據是否配置了延遲加載來決定如何執行,如未配置延遲加載則從數據庫中直接獲 取。在從數據庫獲取到數據的狀況下,Hibernate會相應地填充一級緩存和二級緩存,如配置了延遲加載則直接返回一個代理類,只有在觸發代理類的調用 時才進行數據庫的查詢操做。
在Session一直打開的狀況下,並在該對象具備單向關聯維護的時候,須要使用相似Session.clear(),Session.evict()的方法來強制刷新一級緩存。
get()方法
get()方法與load()方法的區別就在於不會查找二級緩存。在當前Session的一級緩存中獲取不到指定的對象時,會直接執行查詢語句從數據庫中得到所須要的數據。
在Hibernate查詢方法中,能夠經過HQL來執行對數據庫的查詢操做。具體的查詢是由Query對象的list()和iterator()方法來執行的。這兩個方法在執行查詢時的處理方法存在着必定的差異,在開發中應該依據具體的狀況來選擇合適的方法。
list()方法
在執行Query的list()方法時,Hibernate查詢方法是首先檢查是否配置了查詢緩存,如配置了則從查詢緩存中尋找是否已經對該查詢進行了緩 存,如獲取不到則從數據庫中進行獲取。從數據庫中獲取到後,Hibernate將會相應地填充一級、二級和查詢緩存。如獲取到的爲直接的結果集,則直接返 回,如獲取到的爲一些ID的值,則再根據ID獲取相應的值(Session.load()),最後造成結果集返回。能夠看到,在這樣的狀況下,list ()方法也是有可能形成N次查詢的。
查詢緩存在數據發生任何變化的狀況下都會被自動清空。
iterator()方法
Query的iterator()方法處理查詢的方式與list()方法是不一樣的,它首先會使用查詢語句獲得ID值的列表,而後再使用Session的load()方法獲得所須要的對象的值。
在獲取數據的時候,應該依據這4種獲取數據方式的特色來選擇合適的方法。在開發中能夠經過設置show_sql選項來輸出Hibernate所執行的SQL語句,以此來了解Hibernate查詢方法是如何操做數據庫的
HQL 鏈接查詢
內連接  : 根據兩表的外鍵查詢 inner join  
 
外連接 : 左鏈接 , rigth 右鏈接  , left    
fetch 關鍵詞 返回的是對象 在使用時必定要注意
本地查詢:
本地查詢使用是的Hibernate 的配置文件  添加<Query name="example"> <![CDTAT[
HQL語句   ;;;;
]]</Query>
本地SQL查詢:
配置文件 Hibernate 的 <sql-query>
                                  <![CDTAT[
HQL語句   ;;;;
]]
<return></return>
                                <sql-query>
方便使用Hibernate 配置  儘可能少寫sql 語句
Hibernate 查詢方法
Query
實體查詢:
String hql=」from User user 」;  
          List list=session.CreateQuery(hql).list();
屬性查詢:
List list=session.createQuery(「select user.name from User user 」).list();  
for(int i=0;i<list.size();i++){  
System.out.println(list.get(i));  
List list=session.createQuery(「select user.name,user.age from User user 」).list();  
for(int i=0;i<list.size();i++){  
Object[] obj=(Object[])list.get(i);  
System.out.println(obj[0]);  
System.out.println(obj[1]);  
分組和排序 
order by  
from users  u where  order by u.name desc
Group By 分組統計 MAX() MIN() COUNT() AVG() SUM()
優化數據查詢
參數綁定: (jdbc參數)
PrepareStatement pre=connection.prepare(「select * from User where user.name=?」);  
pre.setString(1,」zhaoxin」);  
ResultSet rs=pre.executeQuery(); 
按參數名稱綁定:

在HQL語句中定義命名參數要用」:」開頭,形式以下:

Query query=session.createQuery(「from User user where user.name=:customername and user:customerage=:age 」);  
query.setString(「customername」,name);  
query.setInteger(「customerage」,age); 
上面代碼中用:customername和:customerage分別定義了命名參數customername和customerage,而後用Query接口的setXXX()方法設定名參數值,setXXX()方法包含兩個參數,分別是命名參數名稱和命名參數實際值。

按參數位置邦定:

在HQL查詢語句中用」?」來定義參數位置,形式以下:

Query query=session.createQuery(「from User user where user.name=? and user.age =? 」);  
query.setString(0,name);  
query.setInteger(1,age); 
一樣使用setXXX()方法設定綁定參數,只不過這時setXXX()方法的第一個參數表明邦定參數在HQL語句中出現的位置編號(由0開始編號),第二個參數仍然表明參數實際值。

注:在實際開發中,提倡使用按名稱邦定命名參數,由於這不但能夠提供很是好的程序可讀性,並且也提升了程序的易維護性,由於當查詢參數的位置發生改變時,按名稱邦定名參數的方式中是不須要調整程序代碼的。
   使用綁定參數的優點:

 咱們爲何要使用綁定命名參數?任何一個事物的存在都是有其價值的,具體到綁定參數對於HQL查詢來講,主要有如下兩個主要優點:

①、                      能夠利用數據庫實施性能優化,由於對Hibernate來講在底層使用的是PrepareStatement來完成查詢,所以對於語法相同參數不一樣的SQL語句,能夠充分利用預  編譯SQL語句緩存,從而提高查詢效率。

②、 能夠防止SQL Injection安全漏洞的產生:
 SQL        Injection是一種專門針對SQL語句拼裝的攻擊方式,好比對於咱們常見的用戶登陸,在登陸界面上,用戶輸入用戶名和口令,這時登陸驗證程序可能會生成以下的HQL語句:
Criteria
語法   Criteria cri = session.createCriteria(Student.class);
cri.add(Example.create(s)); //s是一個Student對象
list cri.list();
HQL運算符 QBC運算符 含義
=Restrictions.eq()等於
<> Restrictions.not(Exprission.eq())  不等於
>Restrictions.gt()大於
>= Restrictions.ge()大於等於
<= Restrictions.le()小於等於
is null Restrictions.isnull()  等於空值
is not nullRestrictions.isNotNull()  非空值
like  Restrictions.like() 字符串模式匹配
and Restrictions.and()  邏輯與
and Restrictions.conjunction()邏輯與
or Restrictions.or()邏輯或
or Restrictions.disjunction()邏輯或
notRestrictions.not()  邏輯非
in(列表) Restrictions.in()等於列表中的某一個值
ont in(列表)Restrictions.not(Restrictions.in())不等於列表中任意一個值
between x and yRestrictions.between() 閉區間xy中的任意值
not between x and y  Restrictions.not(Restrictions..between()) 小於值X或者大於值y
相關文章
相關標籤/搜索