Hibernate:查詢

来源:https://www.cnblogs.com/progor/archive/2018/07/31/9393641.html
-Advertisement-
Play Games

本文內容 OID查詢 對象導航查詢 HQL查詢 QBC查詢 SQL查詢 首發日期:2018-07-31 hibernate的查詢方式: hibernate有很多查詢方式 OID查詢 對象導航查詢: HQL查詢: QBC查詢: SQL查詢: OID查詢: OID查詢:基於唯一標識屬性(主鍵)來查詢 使... ...



本文內容

  • OID查詢
  • 對象導航查詢
  • HQL查詢
  • QBC查詢
  • SQL查詢

 

首發日期:2018-07-31


hibernate的查詢方式:

hibernate有很多查詢方式

  • OID查詢
  • 對象導航查詢:
  • HQL查詢:
  • QBC查詢:
  • SQL查詢:

OID查詢:

OID查詢:基於唯一標識屬性(主鍵)來查詢

  • 使用方法:session.get(持久類.class,主鍵值)或session.load(持久類.class,主鍵值)
public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Person p1 = session.get(Person.class, 1L);//因為我用的是Long,所以這裡給個1L
        Person p2 = session.load(Person.class, 2L);//不會立即發生sql語句
        System.out.println(p1);
        System.out.println(p2);//這裡才發送p2的查詢
    }

 

 

get和load的區別:

load是延遲載入的,意思是當調用load的時候,並不立即發送SQL語句,只有當使用了這個對象的時候才去發送SQL語句。

而且,get對於不存在的對象的查詢返回的是null,load會報錯。

 

 


對象導航查詢

對象導航查詢:利用對象之間的關係來獲取【前提--對象之間建立了關係,比如給某個學生選擇了班級,那麼就可以通過這個學生來查詢到班級,而無法通過這個學生查詢到沒有跟他綁定的班級】

  • 使用方法:利用對象的關係【參照例子幫助瞭解,以一對多關係為例。】
public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Student student = session.get(Student.class, 1L);
        Grade grade = student.getGrade();
        System.out.println(grade);
        Grade grade2 = session.get(Grade.class, 1L);
        for (Student s : grade2.getStudents()) {
            System.out.println(s);
        }
        
    }

 

 


HQL查詢:

HQL是hibernate版本的SQL語句,HQL與SQL相像,不過它的表名變成了類名,欄位名變成了屬性名。

  • 執行HQL查詢:Query query = session.createQuery(HQL語句);
  • 獲取結果:query.list()【獲取結果集】、query.unique()【如果只查單行單列數據,用這個】

 

查詢所有:

HQL中的"from 類名"相當於SQL中的“select * from 表名”

public void test3() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student ");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }
        
    }

 

別名查詢

HQL中也給可以給類名指定一個別名。

public void test4() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select s from Student s ");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }

 

排序查詢:

HQL的排序查詢也類似於SQL,不過它的排序條件是類的屬性名

public void test5() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student order by id desc");
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }

 

條件查詢:

HQL的條件查詢也類似於SQL,不過它的條件中欄位名是類的屬性名

條件都是跟在from 類名後面,不過設置值的方法有三種:

  1. 直接設置
  2. 使用?占位,然後使用setParameter(下標,值)設置【不過好像一些版本不再支持這個】
  3. 使用:XXX占位,然後是setParameter(XXX,值)設置
public void test6() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //方式1
//        Query query = session.createQuery("from Student where id = 1");
        //方式2
//        Query query = session.createQuery("from Student where name = ?");
//        query.setParameter(0, "李白");
        //方式3
        Query query = session.createQuery("from Student where id = :aaa");
        query.setParameter("aaa", 1L);
        List<Student> list = query.list();
        for(Student s :list) {
            System.out.println(s);
        }
    }

 

 

投影查詢:

投影查詢就是查詢對象的某個或某些屬性,這個用法與SQL基本相同。不過這個時候使用query.list得出的結果是Object類型的。

public void test7() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select name from Student");
        List<Object> list = query.list();
        //如果你的Student有合適參數的構造函數,那麼你可以這樣用,這會幫你封裝到對象中,返回的也是Student對象
//        Query query = session.createQuery("select new Student(id,name) from Student");
//        List<Student> list = query.list();
        
        for(Object s :list) {
            System.out.println(s);
        }
    }

 

 

分頁查詢:

HQL分頁查詢的核心函數是setMaxResult(一頁顯示的條數),setFirstResult(第一條記錄的索引值)

public void test8() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("from Student");
        query.setMaxResults(3);
        query.setFirstResult(0);
        List<Student> list = query.list();
        
        for(Student s :list) {
            System.out.println(s);
        }
    }

 

 

分組統計查詢:

HQL分組統計查詢與SQL的分組統計查詢的語法相類似。

public void test9() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Query query = session.createQuery("select count(*) from Student group by grade");//這樣得出的是Object[]類型的數據
        List<Object > list = query.list();
        
        for(Object o :list) {
            System.out.println(o);
        }
    }

 

 

多表查詢:

HQL的多表查詢有幾個不同

1.它不是使用表名,它使用持久類的類名

2.它可以使用映射外鍵,比如:from Student s inner join Grade g on s.grade=g.id

3.使用持久類的類名之後,它可以直接利用關聯關係來進行連接,例如:from Student s inner join s.grade

public void test10() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //內連接
//        Query query = session.createQuery("from Student s inner join s.grade");//這樣得出的是Object[]類型的數據
//        Query query = session.createQuery("from Student s inner join Grade g on s.grade=g.id");//這樣得出的是Object[]類型的數據
//        List<Object[] > list = query.list();
//        for(Object[] o :list) {
//            System.out.println(Arrays.toString(o));
//        }
        //左外連接
//        Query query = session.createQuery("from Student s left  join s.grade");//這樣得出的是Object[]類型的數據
//        Query query = session.createQuery("from Student s left  join Grade g on s.grade=g.id");//這樣得出的是Object[]類型的數據
//        List<Object[] > list = query.list();
//        for(Object[] o :list) {
//            System.out.println(Arrays.toString(o));
//        }
        //右外連接差不多,這裡不講了
    }

 

多表查詢中有兩個特殊的連接:迫切內連接和迫切左外連接。當利用關聯關係來連接的時候,在後面那個關聯之前加個fetch,效果是把後面那個關聯持久類的內容封裝到前面那個類的實體中。

比如:

image

 

補充:

  • 很多時候都要依靠query.list()來獲取結果,那麼怎麼判斷返回的結果是什麼類型的呢?
    • 查詢結果是單列的時候,是Object
    • 查詢結果是一個個持久類對象的時候,返回的是持久類
    • 查詢結果是多列數據,而且不全是某個持久類的所有數據的時候,返回的是Object[]


QBC查詢

  • QBC(Query By Criteria)查詢是面向對象的查詢
  • 使用方法:Criteria criteria = session.createCriteria(持久類.class);
  • 獲取結果: criteria.list();

 

 

查詢所有:

 

public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }

 

排序查詢:

在查詢所有的基礎上,調用criteria.addOrder()來進行排序,參數Order.desc(根據哪個欄位排序)、Order.asc(根據哪個欄位排序)

public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.addOrder(Order.desc("id"));
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

條件查詢:

在查詢所有的基礎上,調用criteria.add()來增加條件,參數是Restrictions.xxx

Restrictions.xxx常用的有

Restrictions.eq(屬性名,值):相當於條件 where 欄位名 =值

Restrictions.gt(屬性名,值):相當於條件 where 欄位名 >值

Restrictions.ge(屬性名,值):相當於條件 where 欄位名 >=值

Restrictions.lt(屬性名,值):相當於條件 where 欄位名 <值

Restrictions.in(屬性名,集合):相當於條件 where 欄位名 in 值

預設情況下,增加的每一個都是與的條件,要想添加或的條件,要使用Restrictions.or(多個Restrictions.xxxx),這樣裡面的條件都是或的了。

public void test4() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("name", "李白"));
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

分頁查詢:

criteria調用setFirstResult(第一條記錄的索引),調用setMaxResults(一頁顯示的數量)來進行分頁。

public void test3() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.setFirstResult(0);//第一條記錄的索引
        criteria.setMaxResults(3);//一頁顯示多少
        List<Student> list = criteria.list();
        for(Student s:list) {
            System.out.println(s);
        }
        
    }

 

統計查詢:

criteria調用setProjection(Projections.XXX)來進行統計查詢

Projections.XXX有

image

public void test5() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.setProjection(Projections.rowCount());
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        
    }

 

補充:

  • QBC中還有個離線條件查詢DetachedCriteria,這裡暫時不講,以後有空再加上。

 


SQL查詢

SQL查詢就是直接使用SQL語句來查詢

進行查詢:SQLQuery sqlQuery = session.createSQLQuery(SQL語句)

獲取結果:sqlQuery.list()

 

相信你是已經學過SQL語句的。所以這裡就給出怎麼用,不詳細介紹各種查詢了。

直接使用的時候,返回結果是一個個Object[]

public void test1() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //發現提示用法過期了,不過還是介紹一下
        SQLQuery sqlQuery = session.createSQLQuery("select * from student");
        List<Object[] > list = sqlQuery.list();
        for(Object[] o:list) {
            System.out.println(Arrays.toString(o));
        }
    }
但可以使用sqlQuery.addEntity(持久類.class)來把數據封裝到對象中;
public void test2() {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        //發現提示用法過期了,不過還是介紹一下
        SQLQuery sqlQuery = session.createSQLQuery("select * from student");
        sqlQuery.addEntity(Student.class);
        List<Student > list = sqlQuery.list();
        for(Student s:list) {
            System.out.println(s);
        }
    }

 

 



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Spring是什麼? 是一個框架,是一個輕量級的控制反轉和麵向切麵的容器框架 從大小與開銷兩方面而言Spring都是輕量的 通過控制反轉(IoC)的技術達到松耦的目的 提供了面向切麵編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務進行內聚性的開發 包含並管理應用對象的配置和生命周期,這個意義上 ...
  • https://mp.weixin.qq.com/s/Co1LxS2h_ILh9syOmshjZg 什麼是CGI CGI全稱是“公共網關介面”(Common Gateway Interface),HTTP伺服器與你的或其它機器上的程式進行“交談”的一種工具,其程式須運行在網路伺服器上。 CGI可以用 ...
  • 分數的表示 1.如果分數為負,負號放到分子上 2.如果分數為0,分子為0,分母為1 3.分子分母沒有除1以為的公約數(化簡) 分數的化簡 分三步: 1.調整分子分母的負號 2.處理分數為0的情況 3.約分:分子分母絕對值的最大公約數。 ...
  • C++的註釋有兩種 1. 雙斜杠開始到本行結束 (//) 2. 斜杠星開始 星斜杠結束 (/*)(*/) 我們把上次的代碼加上一個比較詳細的註釋。 註釋的目的: 讓代碼閱讀者更清晰的理解編碼者的代碼意義。 註釋的一種錯誤用法 ,/* */的嵌套使用 大家看一下代碼著色就能發現,嵌套使用後的註釋對會出 ...
  • 題意 交互題。 有$k$個值域為$[1, n]$的數。 請在不超過$60$次詢問內找出其中的兩個數。 每次詢問形式為1 x y 交互庫會返回$|x - a| <= |y - b| ? "TAK" : "NIE"$ 其中$a, b$分別是使得$|x - a|,|y - b|$最小的且存在於序列中的數。 ...
  • 父類 子類 測試類 設計思想:用隨機文件流把文件正向讀出並保存到了字元串中,將字元串倒序,顯示到控制台。 文件讀寫 目的 1 掌握文件讀寫的幾種方法 2 FileOutputStream和FileInputStream類的使用。 3 基本數據類型之間的轉換 實現文件讀取後轉換為大寫後寫入到目標文件中 ...
  • 創建實例: String str = new String();str = "String"; 1、char charAt(int index):返回指定索引位置的字元 2、String substring(int beginIndex):返回指定起始位置至字元串末尾的字元串 String subs ...
  • 前言 從文章的標題,就可以清晰地瞭解到,本文是來辨析三個容易將新手弄糊塗的技術名詞。如果,你一眼看過去就知道這三個名詞的區別及關係,那麼,這篇文章你可以不用繼續讀下去了;除非,你是想要看看我有什麼解釋的不對,來糾錯的(來找茬,哈哈),也歡迎留言。 名詞解釋 JPA(Java Persistence ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...