hibernate查詢(二)

  Hibernate query language。hql查詢中關鍵字不區分大小寫,但是類和屬性都是區分大小寫的。

  1.簡單屬性查詢。

  單一屬性查詢,返回屬性結果集列表,元素類型和實體類的相應的類型一致。

 
List students = session.createQuery("select name from Student").list();  
  1.   
  2. for (Iterator iter=students.iterator(); iter.hasNext();) {  
  3.   
  4. String name = (String)iter.next();  
  5.   
  6. System.out.println(name);  
  7.   
  8. }  
List students = session.createQuery("select name from Student").list();

for (Iterator iter=students.iterator(); iter.hasNext();) {

String name = (String)iter.next();

System.out.println(name);

}


 

 //返回結果集屬性列表,元素類型和實體類中的屬性類型一致

多個屬性查詢,多個屬性查詢返回數組對象,對象數組的長度取決於屬性的個數,對象數組中的元素類型與實體類中屬性一致。

  1. List students = session.createQuery("select id, name from Student").list();  
  2.   
  3. for (Iterator iter=students.iterator(); iter.hasNext();) {  
  4.   
  5. Object[] obj = (Object[])iter.next();  
  6.   
  7. System.out.println(obj[0] + ", " + obj[1]);  
  8.   
  9. }  
List students = session.createQuery("select id, name from Student").list();

for (Iterator iter=students.iterator(); iter.hasNext();) {

Object[] obj = (Object[])iter.next();

System.out.println(obj[0] + ", " + obj[1]);

}


 

2.實體對象查詢

List students = session.createQuery("from Student").list();

當然這種hql語句,可以使用別名,as可以省去,如:from Student as s,若是使用select關鍵字,則必須使用別名。如:select s from Student as s.但是不支持select * from Student格式。

查詢中使用list和Iterate區別:

list查詢是直接運行查詢的結果,所以只有一句sql語句。而iterate方法則有可能會產生N+1條sql語句。這是怎麼回事呢?要理解N+1條語句,首先得弄明白iterate是如何執行查詢的?

首先發出一條查詢對象ID的語句,然後根據對象的ID到緩存(緩存的概念上篇博客已經提到)中查找,若是存在查詢出此對象的其他的屬性,否則會發出N條語句,此時的N語句,是剛纔第一次查詢的記錄條數。這種現象就是N+1sql語句。

其中list是默認情況下都發出sql語句,查詢出的結果會放到緩存中,但是它不會利用緩存,即使放進去,下次執行時,仍然繼續發出sql語句。

而:iterate默認情況下會利用緩存,若是緩存中有則不會發出N+1條語句。

3.條件查詢。

這種方式就是傳入參數,使用參數佔位符“?”。也可以使用“:參數名”

java代碼如下:

  1. List students = session.createQuery("select s.id, s.name from Student s where s.name like ?")  
  2.   
  3. .setParameter(0"%0%")  
  4.   
  5. .list();  
  6.   
  7. List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname")  
  8.   
  9. .setParameter("myname",  "%0%")  
  10.   
  11. .list();  
List students = session.createQuery("select s.id, s.name from Student s where s.name like ?")

.setParameter(0, "%0%")

.list();

List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname")

.setParameter("myname",  "%0%")

.list();


 4.使用原生sql語句。

     和咱們原先寫入的sql語句一樣。在此不介紹了。

 5.外置命名查詢。

      這個聽起來有點晦澀,怎麼理解呢?其實通俗的說就是把hql語句寫在外面,寫在映射文件中。使用標籤:

   

  1. <query name="queryStudent">  
  2.   
  3. <![CDATA[ 
  4.  
  5. select s from Student s where s.id <? 
  6.  
  7. ]]>  
  8.   
  9. </query>  
<query name="queryStudent">

<![CDATA[

select s from Student s where s.id <?

]]>

</query>


 

    那在程序中是如何使用此標籤的呢?使用session.getNameQuery(),並進行賦值,代碼如下:

List students = session.getNamedQuery("queryStudent")  
  1.   
  2. .setParameter(010)  
  3.   
  4. .list();  
List students = session.getNamedQuery("queryStudent")

.setParameter(0, 10)

.list();

 

 6.查詢過濾器。

    這個是什麼意思呢?過濾器大家很熟悉吧,不熟悉的可以參考我的以前博客<>.原來我們接觸過編碼過濾器,編碼過濾器就是爲了避免當時每個頁面需要設置編碼格式而提出的。這個查詢過濾器其實也是這個意思。若是代碼都需要某一句sql語句的話,可以考慮使用它。這樣可以避免每次都寫查詢語句。

    使用如下:首先在映射文件中配置標籤:

  1. <filter-def name="testFilter">  
  2.   
  3. <filter-param type="integer" name="myid"/>  
  4.   
  5. </filter-def>  
<filter-def name="testFilter">

<filter-param type="integer" name="myid"/>

</filter-def>

 

  然後程序中如下使用並進行賦值:

session.enableFilter("testFilter")  
  1.   
  2. .setParameter("myid"10);  
session.enableFilter("testFilter")

.setParameter("myid", 10);


7.分頁查詢。

    分頁查詢,這個肯定不陌生,因爲在做drp項目時,做的最多的是分頁,當時使用oracle數據庫,分頁查詢涉及到三層嵌套。直接傳入的參數爲:每頁的大小(記錄數),頁號。

     Hibernate中給我們已經封裝好了,只要設置開始的頁號以及每頁的大小即可,不用親自動手寫嵌套的sql語句。

     代碼如下:

List students = session.createQuery("from Student")  
  1.   
  2. .setFirstResult(1)  
  3.   
  4. .setMaxResults(2)  
  5.   
  6. .list();  
List students = session.createQuery("from Student")

.setFirstResult(1)

.setMaxResults(2)

.list();

 

8.對象導航查詢。

這個什麼意思呢?這個只要是用於一個類的屬性是另一個類的引用。比如:student類中有一個classes屬性。其中的classes也是一個類Class的引用。

當我們查詢的時候可以這樣使用:

  1. List students = session.createQuery("from Student s where s.classes.name like '%t%'")  
  2.   
  3. .list();  
List students = session.createQuery("from Student s where s.classes.name like '%t%'")

.list();


相當於:s.getClasses.getName(),直接使用get後面的屬性,然後首字母小寫。

 這種語法,是不是很熟悉?想想我們在哪是不是也用過?想起來了嗎?估計你猜出來啦,呵呵,是JSTL(jsp standard tag library)中。若是想進一步瞭解,可以參考我的博客哈,當時是轉載滴貌似。

9.連接查詢。

    連接分爲:內連接和外連接,其中外連接分爲左連接,右連接,完全連接。這個跟數據庫中的左右連接其實是一樣的。我們通俗解釋一下:

    左連接:以左邊爲準,右邊即使沒喲匹配的,也要把這條記錄查詢出來,此時沒有匹配的右邊以null填充。

    右連接:以右邊爲準,左邊即使沒有匹配的,也要把這條記錄查詢出來,此時沒有匹配的左邊以null填充。

   完全連接:只要一方存在即可。

   內連接:必須兩方都存在纔可以查詢提取此記錄。

10.統計查詢。

     其實就是查詢count的記錄數。其中查詢出來的額count是long類型。

11.DML風格的操作。

     DML?其實DML=Data Manipulate Language(數據操作語言),舉個例子:

  

  1. session.createQuery("update Student s set s.name=? where s.id<?")  
  2.   
  3. .setParameter(0"王斌")  
  4.   
  5. .setParameter(12)  
  6.   
  7. .executeUpdate();   
session.createQuery("update Student s set s.name=? where s.id<?")

.setParameter(0, "王斌")

.setParameter(1, 2)

.executeUpdate(); 

           

假若原來的名字是:李四,更新完數據庫後變成王斌,若是我們此時取出數據,其姓名是李四還是王斌?按照道理應該是王斌,但是結果確實李四,若不信,可以自己去實踐一下。

這個原因,是因爲更新了數據庫,但是緩存中沒有更新,纔會造成這種數據庫和緩存不同步的問題。

所以,我們應該儘量不使用這種形式。揚其長避其短嘛。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章