日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询

發(fā)布時間:2025/6/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 一、Hibernate 的 HQL 查詢
    • 1.1、查詢所有數(shù)據(jù)
    • 1.2、條件查詢
    • 1.3、排序查詢
    • 1.4、統(tǒng)計(jì)查詢
    • 1.5、分頁查詢
    • 1.6、投影查詢
  • 二、Hibernate 的 QBC 查詢
    • 2.1、基本查詢
    • 2.2、條件查詢
    • 2.3、排序查詢
    • 2.4、統(tǒng)計(jì)查詢
    • 2.5、分頁查詢
    • 2.6、投影查詢
    • 2.7、離線查詢

在 Hibernate 中,查詢方式有 HQL 和 Criteria 查詢兩種方式,HQL是Hibernate Query Language的縮寫,語法類似于 SQL 語句,可以直接使用實(shí)體類名稱及屬性名稱來查詢,它提供更加豐富靈活、更為強(qiáng)大的查詢能力。

Criteria 查詢對查詢條件進(jìn)行了面向?qū)ο蠓庋b,符合編程人員的思維方式,不過HQL(Hibernate Query Language)查詢提供了更加豐富的和靈活的查詢特性,因此 Hibernate將 HQL 查詢方式立為官方推薦的標(biāo)準(zhǔn)查詢方式,HQL 查詢在涵蓋 Criteria 查詢的所有功能的前提下,提供了類似標(biāo)準(zhǔn) SQL 語句的查詢方式,同時也提供了更加面向?qū)ο蟮姆庋b。

一、Hibernate 的 HQL 查詢

HQL 語法類似于 SQL,有 SQL 的關(guān)鍵詞如 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() 方法,獲取查詢的結(jié)果集。

HQL 書寫規(guī)范:

  • 在查詢語句中省略 select 關(guān)鍵字
  • 使用類名稱替代數(shù)據(jù)庫中的表名稱
  • 使用實(shí)體類的屬性名稱代替數(shù)據(jù)庫表中的列名稱
  • HQL 查詢步驟:

  • Query query = session.createQuery(String HQL);:獲取查詢的 Query 對象
  • query.setParameter(arg0,arg1);:設(shè)置查詢條件參數(shù),參數(shù)下標(biāo)從0開始
  • List list = query.list();:獲取查詢結(jié)果集
  • 1.1、查詢所有數(shù)據(jù)

    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 {// 查詢數(shù)據(jù)庫表中的所有數(shù)據(jù)@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()方法,獲取查詢結(jié)果集List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();}}

    1.2、條件查詢

    在條件查詢中,HQL 書寫方式與 SQL 一樣,使用 ? 作為參數(shù)的占位符,通過 setParameter(arg0, arg1) 來設(shè)定參數(shù)的值,其中:

    • arg0:表示參數(shù)的小標(biāo),從 0 開始;
    • arg1:表示參數(shù)的具體值;
    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 testHQL02() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();// 使用session的createQuery(String HQL)獲取 Query 對象Query query = session.createQuery("from User where nickname like ?");// 使用模糊查詢query.setParameter(0, "%螞蟻%");// 使用 query對象的list()方法,獲取查詢結(jié)果集List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();}}

    1.3、排序查詢

    在排序查詢中,HQL 書寫方式與 SQL 一樣,使用 order by 屬性名稱 desc/asc 來進(jìn)行排序。

    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、統(tǒng)計(jì)查詢

    在 Hibernate 中,使用 HQL 語句,也可以使用聚合函數(shù) (count()、avg()、sum()、max()、min())進(jìn)行查詢。使用聚合函數(shù)式, 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 {// 統(tǒng)計(jì)查詢@Testpublic void testHQL04() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Query query = session.createQuery("select count(*) from User");// 使用聚合函數(shù)中,除了使用 group// by進(jìn)行分組的情況下,返回的都是唯一的結(jié)果,此時可以用query的uniqueResult()方法,接收唯一結(jié)果// 使用 Long 類型進(jìn)行接收Long count = (Long) query.uniqueResult();System.out.println(count);} }

    1.5、分頁查詢

    在 Hibernate 的分頁查詢中,通過 query.setFirstResult(0) 和 query.setMaxResults(2) 方法分別設(shè)置查詢的開始位置和每頁顯示的數(shù)量,從而達(dá)到分頁查詢的效果。

  • query.setFirstResult(0):設(shè)置查詢的開始位置,從0開始
  • query.setMaxResults(2):設(shè)置每頁的顯示數(shù)據(jù)量
  • 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 testHQL05() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Query query = session.createQuery("from User");query.setFirstResult(0);query.setMaxResults(2);List<User> list = query.list();for (User user : list) {System.out.println(user);}tx.commit();session.close();}}

    1.6、投影查詢

    在 Hibernate 框架中,當(dāng)我們只需要查出某個對象中的個別屬性的時候,如目前只需要查出用戶的用戶名和密碼兩個屬性,如果使用 HQL 查詢的方式,將會查找出該對象的全部屬性,此時將會降低查詢的速度和浪費(fèi)系統(tǒng)的資源。

    如果我們使用Query query = session.createQuery(select username , password from User); 此時通過 query.list(); 方法,我們得到的結(jié)果集是 List<Object[]> 類型的,不符合面向?qū)ο蟮奶匦?#xff0c;而且結(jié)果集不方便使用。

    為了解決這一問題,Hibernate 也給出了解決方案投影查詢,通過 Query query = session.createQuery("select new User(username,password ) from User"); 此時,通過 query.list() 方法得到的結(jié)果集是 list<User> 類型的,但是其中 User 對象除 username 和 password 以外的屬性均為 null

    需要注意的是:在使用投影查詢中的 HQL 語句中,出現(xiàn)了 new 關(guān)鍵字,這意味著,我們需要在普通Java類中添加所要查詢屬性的有參構(gòu)造函數(shù),此外,為了保證該普通 Java 類符合 JavaBean 的規(guī)范,我們需要聲明其無參構(gòu)造函數(shù),不然程序運(yùn)行時會報(bào)出 org.hibernate.hql.ast.QuerySyntaxException 異常。

    User 實(shí)體類

    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");// 所查詢得到的結(jié)果集仍然是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) 方法創(chuàng)建 Criteria 對象,之后通過 Criteria 對象的 list() 方法獲取查詢結(jié)果集。它是一種面向?qū)ο蟮牟樵兎绞?#xff0c;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) 創(chuàng)建 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 查詢進(jìn)行條件查詢時候,通過 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 查詢進(jìn)行排序查詢時候,通過 Criteria 的 addOrder() 方法,添加排序查詢的條件。addOrder(Order.asc(屬性名稱))進(jìn)行升序查詢和 addOrder(Order.desc(屬性名稱)) 進(jìn)行降序查詢

    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、統(tǒng)計(jì)查詢

    QBC 查詢中,Criteria 通過 criteria.setProjection(Projections.XXX) 方法來設(shè)定聚合函數(shù)。如使用 Projections.rowCount() 獲取數(shù)據(jù)表中的總記錄數(shù),通過 Projections.count("實(shí)體類屬性名稱") 獲取該屬性有屬性值的數(shù)據(jù)條記錄數(shù)。

    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 {// 統(tǒng)計(jì)查詢@Testpublic void testQBC04() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 獲取數(shù)據(jù)庫表中具有uid屬性值的數(shù)據(jù)條數(shù)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) 方法分別設(shè)置查詢的開始位置和每頁顯示的數(shù)量,從而達(dá)到分頁查詢的效果。

  • query.setFirstResult(0):設(shè)置查詢的開始位置,從0開始
  • query.setMaxResults(2):設(shè)置每頁的顯示數(shù)據(jù)量
  • 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 testQBC05() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();tx.begin();Criteria criteria = session.createCriteria(User.class);// 設(shè)置分頁條件criteria.setFirstResult(0);criteria.setMaxResults(2);List<User> users = criteria.list();for (User user : users) {System.out.println(user);}tx.commit();session.close();} }

    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 項(xiàng)目中,客戶端查詢實(shí)體總共經(jīng)以下步驟:

  • 客戶端提交查詢條件;
  • 表現(xiàn)層 servlet 接收到客戶端提交的查詢條件,開啟 Session 和 Transaction,創(chuàng)建 Criteria 對象,將查詢條件封裝到所創(chuàng)建的 criteria 對象中,并將 criteria 對象傳遞到業(yè)務(wù)層;
  • 業(yè)務(wù)層將接收的 criteria 對象傳遞給持久層;
  • 持久層接收 criteria 對象,查詢數(shù)據(jù)庫,并將查詢結(jié)果依次傳遞給業(yè)務(wù)層、表現(xiàn)層,最后傳遞到客戶端;
  • 存在問題:

    此時發(fā)現(xiàn),在表現(xiàn)層中出現(xiàn)了開啟 Session 和 Transaction,創(chuàng)建 Criteria 對象等屬于持久層的操作,不符合 MVC 的程序設(shè)計(jì)規(guī)范,對后期程序的維護(hù)造成壓力;

    解決方式:使用 QBC 查詢的離線查詢,創(chuàng)建 DetachedCriteria 對象,該對象的獲取不需要 Session,可以直接獲得。

  • 客戶端提交查詢條件,
  • 表現(xiàn)層 servlet 接收到客戶端提交的查詢條件,創(chuàng)建 DetachedCriteria 對象,封裝查詢條件;并將 criteria 對象傳遞到業(yè)務(wù)層;
  • 業(yè)務(wù)層將接收的 DetachedCriteria 對象傳遞給持久層;
  • 持久層接收 DetachedCriteria 對象,將其轉(zhuǎn)化成為 Criteria 對象,查詢數(shù)據(jù)庫,并將查詢結(jié)果依次傳遞給業(yè)務(wù)層、表現(xiàn)層,最后傳遞到客戶端;
  • 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 {// 模擬表現(xiàn)層 —— Servlet@Testpublic void servletDetachedCriteria() {// 創(chuàng)建DetachedCriteria對象DetachedCriteria dc = DetachedCriteria.forClass(User.class);// 封裝客戶端提交的查詢條件dc.add(Restrictions.like("nickname", "%螞蟻%"));// 將封裝好查詢條件的DetachedCriteria對象傳遞給業(yè)務(wù)層List<User> users = seviceDetachedCriteria(dc);for (User user : users) {System.out.println(user);}}// 模擬業(yè)務(wù)層代碼public List seviceDetachedCriteria(DetachedCriteria dc) {Session session = null;Transaction tx = null;try {// 獲取與當(dāng)前線程綁定的 Session 對象session = HibernateUtil.getCurrentSession();tx = session.beginTransaction();tx.begin();return daoDetachedCriteria(dc);} catch (Exception e) {tx.rollback();} finally {tx.commit();}return null;}// 模擬持久層代碼public List daoDetachedCriteria(DetachedCriteria dc) {// 獲取當(dāng)前線程綁定的sessionSession session = HibernateUtil.getCurrentSession();// 將業(yè)務(wù)層傳遞的DetachedCriteria對象轉(zhuǎn)化為Criteria對象Criteria criteria = dc.getExecutableCriteria(session);// 返回查詢結(jié)果集return criteria.list();} }

    轉(zhuǎn)載于:https://www.cnblogs.com/martin0319/p/10857736.html

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。