總結
1.HQL (Hibernate Query Language)
- 語法類似sql
- 把sql語句的表名換成了類名,把字段名換成實體類中的屬性
- 具有跨數據庫的優點
2.QBC (Query By Criteria)
- 使用Session實例的createCriteria(XXX.class)方法創建Criteria對象;
- 使用工具類Restrictions的方法為Criteria對象設置查詢條件,Order工具類的方法設置排序方式,Projections工具類的方法進行統計和分組;
- 使用Criteria對象的list()方法進行查詢並返回結果。
3.SQL (Structured Query Language)
- 違背了hibernate的跨平台優點,不易維護,不面向對象。不推薦使用。
HQL示例
參考:https://www.cnblogs.com/jasonjson/p/12430917.html
查詢所有,條件查詢,排序查詢,分頁查詢,統計查詢,投影查詢
import com.utils.HibernateUtils; import org.hibernate.Query; import org.hibernate.Transaction; import org.hibernate.classic.Session; import org.junit.Test; import java.util.List; public class CustomerTestDemo06 { /** * HQL查詢 * 把sql語句的表明換成了類名。把字段名換成實體類中的屬性 */ //查詢所有 @Test public void test01(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); Query query=s.createQuery("from Customer"); List list = query.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //按條件查詢--1.占位符 @Test public void test02(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); Query query=s.createQuery("from Customer where lovel = ? or name like ?"); query.setString(0,"做縣官"); //占位符從0開始的 query.setString(1,"%劉%"); List list = query.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //按條件查詢--2.給占位符取名字 @Test public void test03(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //給參數區名 :名 規范是(:屬性) Query query=s.createQuery("from Customer where lovel = :a or name like :name"); // query.setString("a","做縣官"); //占位符從0開始的 // query.setString("name","%劉%"); //setParameter()方法,此參數類型更靈活 query.setParameter("a","做縣官"); query.setParameter("name","%劉%"); List list = query.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //排序查詢 @Test public void test04(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //order by 列明 desc Query query=s.createQuery("from Customer order by id desc "); List list = query.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } /** * 分頁查詢,hibernate提供高了兩個方法: * setFirstResult(),設置開始查詢記錄索引 * setMaxResults(),設置每頁查詢條數 * */ @Test public void test05(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //order by 列明 desc Query query=s.createQuery("from Customer order by id desc "); query.setFirstResult(3); query.setMaxResults(3); List list = query.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } /** * 統計查詢,使用聚合函數: *count sum avg max min */ @Test public void test06(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //order by 列明 desc Query query=s.createQuery("select count(*) from Customer"); /*List list = query.list(); for (Object o : list) { System.out.println(o); }*/ Object o = query.uniqueResult(); //當返回結果唯一的時候使用此方法 System.out.println(o); tx.commit(); } /** * 投影查詢: * 查詢結果只需要部分字段,不需要全部不,且希望返回的結果是封裝類,而不是Object * 用法:用在HQL語句中new 一個對象,並給對象一個具體的帶參的構造函數 */ @Test public void test07(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //order by 列明 desc Query query=s.createQuery("select new com.bean.Customer(id,name) from Customer"); List list = query.list(); for (Object o : list) { System.out.println(o); } tx.commit(); } }
HBC示例
參考:https://www.cnblogs.com/jasonjson/p/12430917.html
- Criteria 基本查詢,條件查詢,排序查詢,分頁查詢,統計(投影)查詢,
- DetachedCriteria 離線查詢
package com.bean; import com.utils.HibernateUtils; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Transaction; import org.hibernate.classic.Session; import org.hibernate.criterion.*; import org.junit.Test; import java.util.List; public class CustomerTestDemo07 { /** * QBC查詢 * 更加面向對象的查詢方式,它把生成語句的過程全都融入到方法之中 * 效率比HQL查詢慢 */ //基本查詢 @Test public void test01(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //獲取Criteria對象 Criteria criteria = s.createCriteria(Customer.class); List list = criteria.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //條件查詢 @Test public void test02(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //獲取Criteria對象 Criteria criteria = s.createCriteria(Customer.class); //添加查詢條件 criteria.add(Restrictions.eq("lovel", "做縣官")); criteria.add(Restrictions.like("name", "%張%")); List list = criteria.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //分頁查詢 @Test public void test03(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //獲取Criteria對象 Criteria criteria = s.createCriteria(Customer.class); //設置分頁 criteria.setFirstResult(0);//起始下標 criteria.setMaxResults(2); //每頁顯示條數 List list = criteria.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //排序查詢 @Test public void test04(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //獲取Criteria對象 Criteria criteria = s.createCriteria(Customer.class); //添加查詢條件 criteria.addOrder(Order.desc("name")); List list = criteria.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } //統計查詢 //使用sql自帶的聚合函數 @Test public void test05(){ Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //獲取Criteria對象 Criteria criteria = s.createCriteria(Customer.class); //添加查詢條件 criteria.setProjection(Projections.count("id")); Object o = criteria.uniqueResult(); System.out.println(o); tx.commit(); } //離線查詢 //先用離線對象將查詢條件封裝,再交給session @Test public void test06(){ //1.獲取DetachedCriteria離線對象 DetachedCriteria dc=DetachedCriteria.forClass(Customer.class); //2.封裝查詢條件 dc.add(Restrictions.eq("lovel", "做縣官")); dc.add(Restrictions.like("name", "%張%")); //3.獲取session對象,開始事務 Session s=HibernateUtils.getCurrnetSession(); Transaction tx = s.beginTransaction(); //4.將離線對象轉成Criteria對象 //Session s1=HibernateUtils.getCurrnetSession(); Criteria criteria = dc.getExecutableCriteria(s); //5.執行查詢 List list = criteria.list(); for (Object o : list) { System.out.println((Customer)o); } tx.commit(); } }
SQL示例
static List sql() { Session s = HibernateUtil.getSession(); Query q = s.createSQLQuery("select * from user").addEntity(User.class); List<User> rs = q.list(); s.close(); return rs; }
為何有了Criteria,還需要DetachedCriteria?
參考:https://www.cnblogs.com/jinsheng1027/p/11327159.html
我的理解:
為了“解耦”,解除Criteria和session的依賴關系。
HQL與QBC的區別
參考:https://blog.csdn.net/liuchangjie0112/article/details/51567321
兩者優缺點
比較方面 |
HQL檢索方式 |
QBC檢索方式 |
可讀性 |
和SQL查詢語言比較接近,比較容易讀懂 |
QBC把查詢語句肢解為一組Criterion實例。可讀性差。 |
功能 |
功能最強大,支持各種各樣的查詢。 |
沒有HQL的功能強大,例如不支持報表查詢和子查詢,而且對連接查詢也做了很多限制。 |
查詢語句形式 |
應用程序必須提供基於字符串形式的HQL查詢語句。 |
QBC檢索方式封裝了基於字符串形式的查詢語句,提供了更加面向對象的接口。 |
何時被解析 |
HQL查詢語句只有在運行時才會被解析 |
OBC在編譯時就能被編譯,因此更加容易排錯 |
可擴展性 |
不具有擴展性 |
允許用戶擴展Criterion接口 |
對動態查詢語句的支持 |
盡管支持生成動態查詢語句,但是編程很麻煩 |
適合於生成動態查詢語句 |
連接查詢的支持
指定的連接查詢類型 |
HQL語法 |
QBC語法 |
適用范圍 |
內連接 |
inner join或者join |
Criteria.createAlias() |
適用於有關聯關系的持久化類,並且在映射文件中對這種關聯關系作了映射。 |
迫切內連接 |
inner join fetch或者join fetch |
不支持 |
|
隱式內連接 |
|
不支持 |
|
左外連接 |
left outer join或者left join |
不支持 |
|
迫切左外連接 |
left outer join fetch或者left join fetch |
FetchMode.EAGER |
|
右外連接 |
right outer join或者right join |
不支持 |
|
交叉連接 |
ClassA,ClassB |
不支持 |
適用於 |