總結
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 |
不支持 |
適用於 |
