Hibernate - hibernate 有幾種查詢方式


總結

1.HQL (Hibernate Query Language)

  • 語法類似sql
  • 把sql語句的表名換成了類名,把字段名換成實體類中的屬性
  • 具有跨數據庫的優點

2.QBC (Query By Criteria)

這種方式比較 面向對象方式,重點是有三個描述條件的對象:Restrictions,Order,Projections。使用QBC查詢,一般需要以下三個步驟 ( 只有"DetachedCriteria離線查詢"不同, 詳見示例) :
  • 使用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的依賴關系。

 

Criteria是在線的,所以它是由Hibernate Session進行創建的;
DetachedCriteria是離線的,創建時無需Session,它通過2個靜態方法forClass(Class) 或 forEntityName(Name) 進行DetachedCriteria 的實例創建。
 
所以DetachedCriteria也稱為離線條件查詢,即 建立一個DetachedCriteria對象,將查詢的條件等指定好,然后在session.beginTransaction()后將這個對象傳入通常這個對象可以在表示層建立,然后傳入業務層進行查詢。這樣,就解耦了DetachedCriteria與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

不支持

適用於

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM