本章介紹了Hibernate的幾種主要檢索方式:HQL檢索方式、QBC檢索方式、SQL檢索方式。HQL是Hibernate Query Language的縮寫,是官方推薦的查詢語言。QBC是Query By Criteria的縮寫,是Hibernate提供的一個查詢接口。Hibernate是一個輕量級的框架,它容許使用原始SQL語句查詢數據庫。java
6.1 HQL基礎數據庫
HQL是Hiberante官方推薦的Hibernate檢索方式,它使用相似SQL的查詢語言,以面向對象的方式從數據庫中查詢。可使用HQL查詢具備繼承、多態和關聯關係的數據。在檢索數據時應優先考慮使用HQL方式。數組
6.1.1 默認數據庫表和數據session
在講解本章時,在沒有特殊說明時,用到的數據庫均爲joblog,也就是在第4章創建的數據庫。joblog中添加了3個表:學生表student、課程表course和選課表sc。數據結構
學生表student中各字段的結構如圖6-1所示,字段的中文含義在Comment列中。框架
圖6-1 學生表的數據結構hibernate
學生表student中的數據如圖6-2所示,沒有特殊說明時,用到的均爲這6條記錄。對象
此處仍然使用在第4章創建的HibernateProject項目,可是這裏新建了一個包hibernate.ch06,這個包存放本章中的全部代碼。在hibernate.ch06包中創建學生表對應的持久化類Student.java,代碼以下。blog
圖6-2 學生表中的數據繼承
package hibernate.ch06;
//學生類
public class Student {
private Integer id; //對象標識符
private Integer sno; //學號
private String sname; //姓名
private String ssex; //性別
private String sdept; //所在系別
private Integer sage; //年齡
private String saddress; //籍貫
…… //省略了全部的get/set訪問器
}
課程表course中的各個字段的結構如圖6-3所示,字段的中文含義在Comment列中。
圖6-3 課程表的結構
課程表中的數據如圖6-4所示,若是沒有特殊說明,用到的均爲這4條記錄。
圖6-4 課程表的數據
在hibernate.ch06中新建持久化類Course.java類,代碼以下。
package hibernate.ch06;
//課程類
public class Course {
private Integer id; //對象標識符
private Integer cno; //課程號
private String cname; //課程名
private Integer Ccredit; //學分
…… //省略了get/set訪問器
}
選修表sc(sc爲student-course的縮寫)的結構如圖6-5所示,字段的中文含義在Comment列中。
圖6-5 選修表的結構
選修表中的數據如圖6-6所示,沒有特殊說明時,用到的均爲這5條記錄。
圖6-6 選修表的數據
在hibernate.ch06中新建持久化類SC.java,SC.java的代碼以下。
package hibernate.ch06;
//選課類
public class SC implements java.io.Serializable {
private Integer id; //id
private Integer sno; //學號
private Integer cno; //課程號
private Integer grade; //成績
public SC() {
}
…… //省略get/set訪問器
}
後面的章節中將用這3個表和3個持久化類進行講解。
6.1.2 檢索類的全部對象
使用HQL語句能夠檢索出一個類的全部對象,如HQL語句「from Student」表示檢索Student類的全部對象。下面的程序檢索學生類的全部對象。
Query query=session.createQuery("from Student"); //建立Query對象
List list=query.list(); //執行查詢
//如下代碼作顯示用,之後再也不寫出來
Iterator it=list.iterator();
while(it.hasNext()){
Student stu=(Student)it.next();
System.out.println("id"+stu.getId());
System.out.println("name"+stu.getSname());
System.out.println("/n");
}
session.createQuery()以HQL查詢語句爲參數,生成一個查詢對象。本例中的HQL語句爲「from Student」,這是from子句,格式以下。
from 類名
其中,類名能夠爲類的全限定名,如:
from hibernate.ch06.Student
Hibernate使用自動引入功能(auto import),會自動尋找須要的類,因此不推薦使用類的全限定名。注意,類名區分大小寫,若是寫成from student,將會拋出如下異常。
java.lang.NoClassDefFoundError: hibernate/ch06/student (wrong name: hibernate/ch06/Student)
HQL關鍵字不區分大小寫,FROM、from和From是同樣的。
調用query.list()時,真正開始執行HQL查詢語句,並把查詢的結果放在List中。
本例中查詢的是Student類中的全部屬性,若是查詢Student類中的某一個或某幾個屬性,如查詢全部學生的姓名和所在系,須要用到屬性查詢。
6.1.3 檢索類的某幾個屬性
與SQL語句相似,HQL語句能夠檢索類的某一個或者某幾個屬性。如下代碼查詢全部學生的姓名和所在系。
//建立Query對象
Query query=session.createQuery("select Student.sname,Student.sdept from Student");
List list=query.list();
//執行查詢
//如下代碼顯示查詢的信息
Iterator it=list.iterator();
while(it.hasNext()){
Object[] stu=(Object[])it.next();
System.out.println("id"+stu[0]);
System.out.println("name"+stu[1]);
System.out.println("/n");
}
屬性查詢使用select關鍵字,屬性查詢的格式以下。
select 屬性1,屬性2,… from 類名
屬性前能夠加上類名加以限定,如:
select 屬性1,屬性2,… from 類名
但通常沒有必要。
屬性查詢區分大小寫,上面的代碼中若是寫成:
select SNAME,Sdept from Student
將拋出異常,提示找不到屬性SNAME和屬性Sdept。
查詢結果將只顯示查詢的屬性列。
屬性查詢的結果,對於用it.next()得到的每條記錄,能夠存儲在Object[]數組中,以便進行存取。
6.1.4 指定別名
在查詢時,能夠用關鍵字as指定查詢的別名,指定別名能夠簡化查詢,有時必需指定別名才能進行查詢。如下代碼查詢學號中含有4的學生的姓名和所在系。
select s.sname,s.sdept from Student as s where s.sno like '%4%'from Student s
s就是類Student的別名。注意as能夠省略,即下面的查詢語句和上面的語句是等效的。
select s.sname,s.sdept from Student s where s.sno like '%4%'from Student s
6.1.5 where條件子句
where條件子句跟SQL中的where條件子句相似,它檢索符合條件的對象。例如,查詢全部所在系別爲計算機系的學生:
select s.sname,s.sdept from Student s where s.dept=’計算機’
where子句指定查詢的條件,其語法和SQL相似。
在where子句中能夠指定比較運算符:>、>=、<、<=、<>,其含義分別爲大於、大於等於、小於、小於等於、不等於。
查詢年齡在22到23歲的學生:
from Student s where s.sage>=22 and s.sage<=23
在where子句中指定查詢的屬性是否爲null:is null、is not null,其含義分別表示爲空和不爲空。
查詢所在籍貫爲空的學生:
from Student s where s.saddress is null
6.1.6 使用distinct過濾掉重複值
使用distinct關鍵字將去掉結果中的重複值,只檢索符合條件的對象。以下面的例子檢索學生實例中的不重複的年齡。
Session session=HibernateSessionFactory.currentSession(); //建立Session
String hql="select distinct s.sage from Student s"; //HQL查詢語句
Query query=session.createQuery(hql); //建立查詢
List list=query.list(); //執行查詢
檢索的結果以下,可見結果中去掉了一個重複的22歲。