Hibernate 之強大的HQL查詢


Hibernate  配備了一種非常強大的查詢語言,這種語言看上去很像  SQL。但是不要被語法結構上的相似所迷惑,HQL  是非常有意識的被設計為完全面向對象的查詢,它可以理解如繼承、多態和關聯之類的概念。

 

基本規則

  1. HQL語法類似於SQL,也是一種select from結構的語句。但是他后面跟的不是表名和字段名,而是類名和屬性名。
  2. HQL基本查詢語法跟SQL很類似
  3. HQL大小寫不敏感。但是,設計java類名、包名、屬性名時大小寫敏感。
  4. 包名的使用情況。比如:如果注冊的實體類Emp只有一個類,那么查詢時可以不加包名,hibernate會自動檢索到Emp類。但是如果注冊多個實體類,名字都叫Emp。此時就要增加包名來區別多個實體類。

第一個HQL查詢

 1 package com.qcf.test;
 2 
 3 import java.util.List;
 4 
 5 
 6 import org.hibernate.Query;
 7 import org.hibernate.Session;
 8 import org.hibernate.SessionFactory;
 9 import org.hibernate.Transaction;
10 import org.hibernate.cfg.Configuration;
11 
12 import com.qcf.po.User;
13 
14 public class TestHiber {
15     public static void main(String[] args) {
16         //讀取配置文件中的信息
17         Configuration con=new Configuration().configure();
18         //獲取sessionFactory對象
19         SessionFactory factory=con.buildSessionFactory();
20         //獲取Session對象
21         Session session=factory.openSession();
22         String hql="from User";
23         //創建HQL查詢
24         Query query= session.createQuery(hql);
25         List list=query.list();
26         //對查詢的結果進行遍歷
27         for (int i = 0; i < list.size(); i++) {
28             User user=(User) list.get(i);
29             System.out.println(user.getName());
30         }
31         
32         session.close();
33     }
34 }
View Code

查詢結果:

 

根據返回類型划分HQL查詢

  1、單個對象

  在這里提醒一下,這個hql意識統計數據庫的記錄數,一般我們都知道count(1) 要比count(*) 快多了,但是這里必須使用count(*) 使用count(1)就會報錯!

 1 package com.qcf.test;
 2 
 3 import java.util.List;
 4 
 5 
 6 import org.hibernate.Query;
 7 import org.hibernate.Session;
 8 import org.hibernate.SessionFactory;
 9 import org.hibernate.Transaction;
10 import org.hibernate.cfg.Configuration;
11 
12 import com.qcf.po.User;
13 
14 public class TestHiber {
15     public static void main(String[] args) {
16         //讀取配置文件中的信息
17         Configuration con=new Configuration().configure();
18         //獲取sessionFactory對象
19         SessionFactory factory=con.buildSessionFactory();
20         //獲取Session對象
21         Session session=factory.openSession();
22         String hql="select count(*) from User";
23         //創建HQL查詢
24         Query query= session.createQuery(hql);
25         Number n=(Number) query.uniqueResult();
26         System.out.println(n.intValue());
27         
28         session.close();
29     }
30 }
View Code

  2、List集合

         參考第一個HQL查詢中的內容!

  3、Object[]數組
  有時候,我們不需要講實體類的所有屬性查找出來,只需要查找部分屬性。這時,可以將返回的內容放入Object[]中,而不是實體對象中。

1 String hql="select u.name,u.age from User u";
2         //創建HQL查詢
3         Query q= session.createQuery(hql);
4         List<Object[]> list=q.list();
5         for (int i = 0; i < list.size(); i++) {
6             Object[] os=list.get(i);
7             System.out.println("用戶名是:"+os[0]+"年齡是:"+os[1]);
8         }
View Code

  顯示結果:

  Hibernate: select user0_.username as col_0_0_, user0_.userage as col_1_0_ from user user0_
  用戶名是:哈哈年齡是:18
  用戶名是:三個年齡是:18
  用戶名是:張三年齡是:18
  用戶名是:李四年齡是:18
  用戶名是:王五年齡是:18
  用戶名是:張柳 年齡是:18

 

  4、Map集合

  我們也可以將查詢后的結果放到map中

1 String hql="select new map(u.name as name,u.age as age) from User u";
2         //創建HQL查詢
3         Query q= session.createQuery(hql);
4         List<Map> list=q.list();
5         for (int i = 0; i < list.size(); i++) {
6             Map map=list.get(i);
7             System.out.println("用戶名"+map.get("name")+"年齡"+map.get("age"));
8         }
9         session.close();
View Code

  顯示結果:

  Hibernate: select user0_.username as col_0_0_, user0_.userage as col_1_0_ from user user0_
  用戶名哈哈年齡18
  用戶名三個年齡18
  用戶名張三年齡18
  用戶名李四年齡18
  用戶名王五年齡18
  用戶名張柳 年齡18

  5、實體對象

  對於只查詢部分屬性的情況,Object數組、Map都很方便。實際上,我們也可以通過構造方法,將查出的數據直接封裝到實體對象中。

 1     新增構造方法:
 2 public Emp(Short empno, String ename) {
 3         super();
 4         this.empno = empno;
 5         this.ename = ename;
 6 }
 7 String hql = "select new Emp(e.empno,e.ename) from Emp e ";
 8 Query q = session.createQuery(hql);
 9             
10 List<Emp> list = q.list();
11 for(int i=0;i<list.size();i++){
12     Emp e = list.get(i);
13     System.out.println("雇員編號:"+e.getEmpno()+"-雇員名字"+e.getEname()); 
14 }
View Code

 

  6、Where子句和參數傳遞

 1 //            String hql = "from Emp  where ename=?";
 2             String hql = "from Emp where ename=:ename";   //使用參數名稱動態綁定!(推薦使用!)
 3             Query q = session.createQuery(hql);
 4 //            q.setString(0, "SMITH");   //參數索引從0開始計數,而不像jdbc一樣從1開始。
 5             q.setString("ename", "SMITH");
 6             List list = q.list();
 7             for(int i=0;i<list.size();i++){
 8                 Emp c = (Emp) list.get(i);
 9                 System.out.println(c.getEname()); 
10             }
View Code

 

  7、HQL分頁查詢

  分頁顯示是項目中必不可少的功能,不同的數據庫有不同的分頁方式,hibernate替我們屏蔽了數據庫中之間的差異。我們通過如下簡單的代碼即可實現分頁功能(如果分頁的原  理和做法忘記了,可以參考之前講授的項目內容)。

 1     String hql = "from Emp";
 2             Query q = session.createQuery(hql);
 3             q.setFirstResult(0);   //從第幾條開始取數據
 4             q.setMaxResults(10);  //設置每頁最多顯示記錄的個數
 5             
 6             List list = q.list();
 7             for(int i=0;i<list.size();i++){
 8                 Emp c = (Emp) list.get(i);
 9                 System.out.println(c.getEname()); 
10             }
View Code

 

  8、跨表查詢和對象導航

  

  SQL中復雜的表連接查詢,跨表操作。在HQL中進行了相當的簡化,我們只需要簡單的使用屬性即可,類似於我們前面學過的EL表達式。這樣,我們可以用簡單的代碼寫出比較  復雜的查詢。

1             String hql = "from Emp e where e.dept.deptno=? ";
2             Query q = session.createQuery(hql);
3             q.setInteger(0, 10);
View Code

 

  9、Join(內連接、外連接)

         SQL中我們有內連接、右外連接、左外連接、全外連接,在HQL中我們也有這些概念。不過,有如下幾點不一致:

  1. 如果兩個實體類之間沒有任何關系,那么不能使用join
  2. 由於只有兩個實體類之間有關聯關系才能使用join,因此不需要像SQL那樣通過on指明連接條件。

  代碼示例如下:

1 String hql = "select e.ename,d.dname from Emp e left join e.dept d ";
2 
3 Query q = session.createQuery(hql);
View Code

 

  10、SQL原生查詢(Native SQL)

  

  有時候HQL可能不能滿足我們的要求。我們需要使用原始的SQL來完成我們的功能。我們可以通過如下方式,在hibernate中使用SQL查詢:

 1             String sql = "select ename,sal from emp where empno=:id";
 2             SQLQuery q = session.createSQLQuery(sql);
 3             q.setInteger("id", 7369);
 4             List list = q.list();  //返回的結果為List<Object[]>
 5             for(int i=0;i<list.size();i++){
 6                 Object[] c = (Object[]) list.get(i);
 7                 System.out.println(c[0]+"-"+c[1]); 
 8             }
 9             String sql = "select * from emp where empno=:id";
10             SQLQuery q = session.createSQLQuery(sql);
11             q.setInteger("id", 7369);
12             q.addEntity(Emp.class);
13             List<Emp> list = q.list();
14             for(int i=0;i<list.size();i++){
15                 Emp c = list.get(i);
16                 System.out.println(c.getEname()+"-"+c.getSal()); 
17             }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM