Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询
目錄
- 一、Hibernate 的 HQL 查詢
- 1.1、查詢所有數據
- 1.2、條件查詢
- 1.3、排序查詢
- 1.4、統計查詢
- 1.5、分頁查詢
- 1.6、投影查詢
- 二、Hibernate 的 QBC 查詢
- 2.1、基本查詢
- 2.2、條件查詢
- 2.3、排序查詢
- 2.4、統計查詢
- 2.5、分頁查詢
- 2.6、投影查詢
- 2.7、離線查詢
在 Hibernate 中,查詢方式有 HQL 和 Criteria 查詢兩種方式,HQL是Hibernate Query Language的縮寫,語法類似于 SQL 語句,可以直接使用實體類名稱及屬性名稱來查詢,它提供更加豐富靈活、更為強大的查詢能力。
Criteria 查詢對查詢條件進行了面向對象封裝,符合編程人員的思維方式,不過HQL(Hibernate Query Language)查詢提供了更加豐富的和靈活的查詢特性,因此 Hibernate將 HQL 查詢方式立為官方推薦的標準查詢方式,HQL 查詢在涵蓋 Criteria 查詢的所有功能的前提下,提供了類似標準 SQL 語句的查詢方式,同時也提供了更加面向對象的封裝。
一、Hibernate 的 HQL 查詢
HQL 語法類似于 SQL,有 SQL 的關鍵詞如 select 、from 、order by 、count()、where 等,完整的HQL語句形式如下: Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc。
Hibernate 的 HQL 查詢中,通過 Session 對象的 createQuery(String HQL) 方法,獲取 Query 對象, Query 中傳入查詢的 HQL 語句,之后通過 Query對象的 list() 方法,獲取查詢的結果集。
HQL 書寫規范:
HQL 查詢步驟:
1.1、查詢所有數據
package com.hibernate.test;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List;import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestHQL {// 查詢數據庫表中的所有數據@Testpublic void testHQL01() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();// 使用session的createQuery(String HQL)獲取 Query 對象Query query = session.createQuery("from User");// 使用 query對象的list()方法,獲取查詢結果集List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();}}1.2、條件查詢
在條件查詢中,HQL 書寫方式與 SQL 一樣,使用 ? 作為參數的占位符,通過 setParameter(arg0, arg1) 來設定參數的值,其中:
- arg0:表示參數的小標,從 0 開始;
- arg1:表示參數的具體值;
1.3、排序查詢
在排序查詢中,HQL 書寫方式與 SQL 一樣,使用 order by 屬性名稱 desc/asc 來進行排序。
package com.hibernate.test;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List;import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestHQL {// 排序查詢@Testpublic void testHQL03() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Query query = session.createQuery("from User order by uid desc");List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();} }1.4、統計查詢
在 Hibernate 中,使用 HQL 語句,也可以使用聚合函數 (count()、avg()、sum()、max()、min())進行查詢。使用聚合函數式, HQL 語句的寫法如下:
Query query = session.createQuery("select count(*) from User");
package com.hibernate.test;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List;import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestHQL {// 統計查詢@Testpublic void testHQL04() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Query query = session.createQuery("select count(*) from User");// 使用聚合函數中,除了使用 group// by進行分組的情況下,返回的都是唯一的結果,此時可以用query的uniqueResult()方法,接收唯一結果// 使用 Long 類型進行接收Long count = (Long) query.uniqueResult();System.out.println(count);} }1.5、分頁查詢
在 Hibernate 的分頁查詢中,通過 query.setFirstResult(0) 和 query.setMaxResults(2) 方法分別設置查詢的開始位置和每頁顯示的數量,從而達到分頁查詢的效果。
1.6、投影查詢
在 Hibernate 框架中,當我們只需要查出某個對象中的個別屬性的時候,如目前只需要查出用戶的用戶名和密碼兩個屬性,如果使用 HQL 查詢的方式,將會查找出該對象的全部屬性,此時將會降低查詢的速度和浪費系統的資源。
如果我們使用Query query = session.createQuery(select username , password from User); 此時通過 query.list(); 方法,我們得到的結果集是 List<Object[]> 類型的,不符合面向對象的特性,而且結果集不方便使用。
為了解決這一問題,Hibernate 也給出了解決方案投影查詢,通過 Query query = session.createQuery("select new User(username,password ) from User"); 此時,通過 query.list() 方法得到的結果集是 list<User> 類型的,但是其中 User 對象除 username 和 password 以外的屬性均為 null。
需要注意的是:在使用投影查詢中的 HQL 語句中,出現了 new 關鍵字,這意味著,我們需要在普通Java類中添加所要查詢屬性的有參構造函數,此外,為了保證該普通 Java 類符合 JavaBean 的規范,我們需要聲明其無參構造函數,不然程序運行時會報出 org.hibernate.hql.ast.QuerySyntaxException 異常。
User 實體類
package com.hibernate.domain;import java.util.Date;public class User {private Integer uid;private String username;private String password;private String nickname;private String realname;private Date birthday;public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}public String getRealname() {return realname;}public void setRealname(String realname) {this.realname = realname;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public User(String username, String password) {this.username = username;this.password = password;}public User() {}@Overridepublic String toString() {return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", nickname=" + nickname+ ", realname=" + realname + ", birthday=" + birthday + "]";}}投影查詢:
package com.hibernate.test;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List;import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestHQL {// 投影查詢:查詢用戶名和密碼@Testpublic void testHQL06() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Query query = session.createQuery("select new User(username, password) from User");// 所查詢得到的結果集仍然是List<User> 類型List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();}}二、Hibernate 的 QBC 查詢
Hibernate 中的 QBC 查詢方式,全稱為 Query By Criteria,通過 Session 對象的 createCriteria(Class clazz) 方法創建 Criteria 對象,之后通過 Criteria 對象的 list() 方法獲取查詢結果集。它是一種面向對象的查詢方式,QBC 查詢把生成語句的過程全部融入到方法中了。
2.1、基本查詢
package com.hibernate.test;import java.util.List;import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestQBC {// 基本查詢@Testpublic void testQBC01() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();// 使用 createCriteria(Class clazz) 創建 Criteria 對象Criteria criteria = session.createCriteria(User.class);List<User> list = criteria.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();} }2.2、條件查詢
Hibernate QBC 查詢進行條件查詢時候,通過 Criteria 的 add() 方法,添加查詢條件。
package com.hibernate.test;import java.util.List;import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestQBC {// 條件查詢,通過 add()方法添加查詢條件@Testpublic void testQBC02() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 通過 Restrictions 添加具體的條件criteria.add(Restrictions.like("nickname", "%螞蟻%"));List<User> users = criteria.list();for (User user : users) {System.out.println(user);}tx.commit();session.close();} }2.3、排序查詢
Hibernate QBC 查詢進行排序查詢時候,通過 Criteria 的 addOrder() 方法,添加排序查詢的條件。addOrder(Order.asc(屬性名稱))進行升序查詢和 addOrder(Order.desc(屬性名稱)) 進行降序查詢
package com.hibernate.test;import java.util.List;import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestQBC {// 排序查詢@Testpublic void testQBC03() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 通過 addOrder() 添加排序條件criteria.addOrder(Order.desc("uid"));List<User> users = criteria.list();for (User user : users) {System.out.println(user);}tx.commit();session.close();} }2.4、統計查詢
QBC 查詢中,Criteria 通過 criteria.setProjection(Projections.XXX) 方法來設定聚合函數。如使用 Projections.rowCount() 獲取數據表中的總記錄數,通過 Projections.count("實體類屬性名稱") 獲取該屬性有屬性值的數據條記錄數。
package com.hibernate.test;import java.util.List;import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestQBC {// 統計查詢@Testpublic void testQBC04() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 獲取數據庫表中具有uid屬性值的數據條數criteria.setProjection(Projections.count("uid"));Long count = (Long) criteria.uniqueResult();System.out.println(count);tx.commit();session.close(); } }2.5、分頁查詢
QBC 和 HQL 中的分頁查詢所用的方法和方法的含義是一模一樣的。通過 query.setFirstResult(0) 和 query.setMaxResults(2) 方法分別設置查詢的開始位置和每頁顯示的數量,從而達到分頁查詢的效果。
2.6、投影查詢
package com.hibernate.test;import java.util.List;import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import com.hibernate.domain.User; import com.hibernate.utils.HibernateUtil;public class TestQBC {// 投影查詢@Testpublic void testQBC06() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 通過Projections.projectionList().add()添加所要查詢的屬性名criteria.setProjection( Projections.projectionList().add(Property.forName("username")).add(Property.forName("password")));List<User> users = criteria.list();for (User user : users) {System.out.println(user);}tx.commit();session.close();} }2.7、離線查詢
在 JavaWeb 項目中,客戶端查詢實體總共經以下步驟:
存在問題:
此時發現,在表現層中出現了開啟 Session 和 Transaction,創建 Criteria 對象等屬于持久層的操作,不符合 MVC 的程序設計規范,對后期程序的維護造成壓力;
解決方式:使用 QBC 查詢的離線查詢,創建 DetachedCriteria 對象,該對象的獲取不需要 Session,可以直接獲得。
轉載于:https://www.cnblogs.com/martin0319/p/10857736.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【干货】SqlServer 总结几种存储
- 下一篇: 数据对比