Hibernate HQL詳解
小編:管理員 450閱讀 2022.09.14
前言:
HQL(Hibernate Query Language) 是Hibernate框架提供的一種查詢機制,它和 SQL 查詢語言很相似。不同的是HQL是面向對象的查詢語言,讓開發者能夠以面向對象的思想來編寫查詢語句,對Java編程來說是很好的一種方式。
但是HQL語言是不能直接與數據庫進行交互的,它是中間層的語言,Hibernate框架會將其翻譯成底層數據庫能夠識別的SQL語言,與數據庫進行交互。
運行流程:

需要注意的是,HQL語言不能直接進行insert操作,select,delete,update是支持的。
代碼:
1.實體對象查詢
查詢表中的所有數據,自動完成對象封裝,返回List集合。
HQL進行查詢操作,若省略select關鍵字,則查詢所有字段,from關鍵字后面不能寫表名,必須寫數據表對應的實體類名。
String hql = "from News"; Query query = session.createQuery(hql); List復制list = query.list(); for(News news : list){ System.out.println(news); }

2.分頁查詢
HQL分頁查詢可以通過調用query的方法來完成。
1.setFirstResult():設置截取的起始下標。
2.setMaxResults():設置截取記錄的長度。
String hql = "from News"; Query query = session.createQuery(hql); //設置截取的起始下標 query.setFirstResult(2); //設置截取的記錄長度 query.setMaxResults(3); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }

3.where條件查詢
HQL直接追加where關鍵字設置查詢條件,與SQL沒有區別。
String hql = "from News where id = 1"; Query query = session.createQuery(hql); News news= (News) query.list().get(0); System.out.println(news);復制
query.list()返回的是一個集合,此時集合中只有一個對象,通過下標0取出該對象,需要強轉成News對象,因為query.list().get(0)拿到的是Object類型的對象,向下轉型成子類News對象。
這種方式存在一個問題,若id=0時,查詢不到對象,集合為空,使用get(0)會拋出下標越界異常。

推薦使用另外一種方式,通過uniqueResult()方法,該方法返回一個Object對象,如果對象不存在則返回null,不會拋出異常。
String hql = "from News where id = 1"; Query query = session.createQuery(hql); News news= (News) query.uniqueResult(); System.out.println(news);復制
4.模糊查詢
查詢作者名包含“三”的所有記錄。
String hql = "from News where author like '%三%'"; Query query = session.createQuery(hql); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }

5.order by
按照createTime降序排列。
String hql = "from News order by createTime desc"; Query query = session.createQuery(hql); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }

6.group by
用author分組查詢。
String hql = "from News group by author"; Query query = session.createQuery(hql); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }

7.group by having
用author分組查詢,并且id>2。
String hql = "from News group by author having id > 2"; Query query = session.createQuery(hql); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }

8.查詢實體對象的屬性
查詢一個屬性,返回Object類型的對象。
String hql = "select title from News where id = 1"; Query query = session.createQuery(hql); String title = (String) query.uniqueResult(); System.out.println(title);復制
查詢多個屬性,返回List
String hql = "select title,author,createTime from News where id = 1"; Query query = session.createQuery(hql); List復制
查詢屬性,并且封裝成對象。
String hql = "select new News(title,author) from News where id = 1"; Query query = session.createQuery(hql); News news = (News) query.uniqueResult(); System.out.println(news);復制
HQL可以通過new關鍵字返回一個對象,并且將查詢出的字段值賦給對應的屬性,要求實體類必須有一個對應的構造函數,否則直接報錯。
如new News(title,author) 就要求News類中必須有如下構造函數。
public News(String title, String author) { this.title = title; this.author = author; }復制
9.占位符
HQL的占位符通過下標進行替換。
需要注意的是HQL中占位符的下標從0開始,JDBC的占位符下標從1開始。
使用query的set*方法來替換變量,根據變量的類型來決定調用哪個方法。
如int類型則調用setInteger(),String類型調用setString()。
String hql = "from News where author = ?"; Query query = session.createQuery(hql); query.setString(0, "張三"); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }
10.參數
跟占位符類似,用變量替換HQL語句中的值,需要注意的是在HQL語句中參數名前要加:。
String hql = "from News where author = :name"; Query query = session.createQuery(hql); query.setString("name", "張三"); List復制list = (List ) query.list(); for(News news:list){ System.out.println(news); }
11.級聯查詢
用Customer和Orders舉例,
查詢name="張三"的Customer對象所有訂單信息
使用SQL查詢,通過外鍵cid將兩張表進行關聯。
select * from orders where cid = (select id from customer where name = "張三");復制
HQL是面向對象的查詢語言,所以不需要通過數據表的外鍵關聯,可直接通過實體類的級聯關系進行設置。
//查詢name=張三的customer對象 String hql = "from Customer where name = ?"; Query query = session.createQuery(hql); query.setString(0, "張三"); Customer customer = (Customer) query.uniqueResult(); //查詢customer對象所有的orders對象 String hql2 = "from Orders where customer = ?"; Query query2 = session.createQuery(hql2); //替換變量 query2.setEntity(0, customer); List復制list = (List ) query2.list(); for(Orders orders:list){ System.out.println(orders); }
從上面的代碼可以看出,直接調用query的setEntity()方法,即可將占位符替換為customer對象,這個查詢語句就是面向對象查詢最直接的的體現。
相關推薦
- 經典筆試題-JDBC及Hibernate篇 五、JDBC 及Hibernate:(共12 題:基礎10 道,中等難度2 道)110、數據庫,比如100 用戶同時來訪,要采取什么技術解決?【基礎】 答:可采用連接池。111、什么是ORM?【基礎】 答:對象關系映射(Object—Relational Mapping,簡稱ORM)是一種為了解決面向對象…
- Hibernate Criterion 在查詢方法設計上能夠靈活的依據Criteria的特點來方便地進行查詢條件的組裝.Hibernate設計了CriteriaSpecification作為Criteria的父接口,以下提供了Criteria和DetachedCriteria.Criteria和DetachedCriteria的主要差別在于創建的形式不一樣,Criteria是在線的,所…