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類型的對象,集合保存的對象是一個Object類型的數組。

String hql = "select title,author,createTime from News where id = 1";
Query query = session.createQuery(hql);
List list = (List) query.list();
for(Object obj:list){
    System.out.println(Arrays.toString((Object[])obj));
}
復制

查詢屬性,并且封裝成對象。

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對象,這個查詢語句就是面向對象查詢最直接的的體現。

關聯標簽:
亚洲国产欧美图片,亚洲aⅴ在线av,日韩亚洲综合图片视频,日本av精品在线中文