<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Hibernate HQL(Hiberate 查詢語言)示例 > 原文: [https://howtodoinjava.com/hibernate/complete-hibernate-query-language-hql-tutorial/](https://howtodoinjava.com/hibernate/complete-hibernate-query-language-hql-tutorial/) 在本 **HQL 教程**中,了解什么是 Hiberate 查詢語言,各種語句的 hql 語法,命名查詢和本機 sql 查詢,關聯和聚合等。 HQL 是一種類似于 SQL 的面向對象的查詢語言,但是 HQL 不會對表和列進行操作,而是處理持久化對象及其屬性。 這是 **hql 與 sql** 之間的主要區別。 HQL 是 JPQL(Java 持久化查詢語言)的超集。 JPQL 查詢是有效的 HQL 查詢,但并非所有 HQL 查詢都是有效的 JPQL 查詢。 HQL 是一種具有自己的語法和語法的語言。 它以字符串形式編寫,例如`from Product p`。 Hibernate 將 HQL 查詢轉換為常規 SQL 查詢。 [Hibernate](//howtodoinjava.com/hibernate-tutorials/ "Hibernate Tutorials") 還提供了一個 API,它使我們也可以直接發出 SQL 查詢。 請注意,Hibernator 的查詢功能不允許您更改數據庫結構。 我們只能更改表中的數據。 ```java Table Of Contents 1\. HQL Syntax 1.1\. Update Operation 1.2\. Delete Operation 1.3\. Insert Operation 1.4\. Select Operation 2\. The from Clause and Aliases 3\. The select Clause and Projection 4\. Using Named Parameters 5\. Paging Through the Result Set 6\. Obtaining a Unique Result 7\. Sorting Results with the order by Clause 8\. Associations 9\. Aggregate Methods 10\. Named Queries 11\. Using Native SQL 12\. Enable Logging and Commenting ``` 讓我們更詳細地討論每一項,從基本內容到更復雜的概念。 ## 1\. HQL 語法 HQL 語法定義為 [**ANTLR**](https://en.wikipedia.org/wiki/ANTLR "ANTLR") 語法。 語法文件包含在 Hibernate 核心下載的語法目錄中。 (*ANTLR 是用于構建語言解析器*的工具)。 讓我們在這里概述四個基本 CRUD 操作的語法: #### 1.1 HQL 更新語句 `UPDATE`更改數據庫中現有對象的詳細信息。 不管是否受管,內存中實體都不會更新以反映由于發出`UPDATE`語句而導致的更改。 這是`UPDATE`語句的語法: ```java UPDATE [VERSIONED] [FROM] path [[AS] alias] [, ...] SET property = value [, ...] [WHERE logicalExpression] ``` * `path` – 一個或多個實體的全限定名稱 * `alias` – 用于縮寫對特定實體或其屬性的引用,并且在查詢中的屬性名稱不明確時必須使用。 * `VERSIONED` – 表示更新將更新時間戳(如果有),該時間戳是要更新的實體的一部分。 * `property` – 在`FROM`路徑中列出的實體的屬性名稱。 * `logicalExpression` – `where`子句。 正在進行的更新示例如下所示。 在此示例中,我們使用 **hql 多列更新查詢**來更新員工數據。 ```java Query query=session.createQuery("update Employee set age=:age where name=:name"); query.setInteger("age", 32); query.setString("name", "Lokesh Gupta"); int modifications=query.executeUpdate(); ``` #### 1.2 HQL 刪除語句 `DELETE`從數據庫中刪除現有對象的詳細信息。 內存中實體將不會更新以反映`DELETE`語句導致的更改。 這也意味著使用 HQL 進行的刪除將不遵循 Hibernate 的級聯規則。 但是,如果您在數據庫級別指定了級聯刪除(直接或通過 Hibernate,使用`@OnDelete`注解),則數據庫仍將刪除子行。 這是`DELETE`語句的語法: ```java DELETE [FROM] path [[AS] alias] [WHERE logicalExpression] ``` 實際上,刪除操作可能如下所示: ```java Query query=session.createQuery("delete from Account where accountstatus=:status"); query.setString("status", "purged"); int rowsDeleted=query.executeUpdate(); ``` #### 1.3 HQL 插入語句 HQL `INSERT`**不能用于直接插入任意實體** - 它只能用于插入從`SELECT`查詢獲得的信息中構造的實體(與普通 SQL 不同,在 SQL 中,可以使用`INSERT`命令插入任意數據,插入表格,以及插入從其他表格中選擇的值)。 這是`INSERT`語句的語法: ```java INSERT INTO path ( property [, ...]) select ``` 實體的名稱是`path`。 屬性名稱是合并的`SELECT`查詢的`FROM`路徑中列出的實體的屬性名稱。 該選擇查詢是 HQL `SELECT`查詢(如下一節所述)。 由于此 HQL 語句只能使用 HQL 選擇提供的數據,因此其應用可能受到限制。 在實際清除用戶之前將用戶復制到清除表的示例可能如下所示: ```java Query query=session.createQuery("insert into purged_accounts(id, code, status) "+ "select id, code, status from account where status=:status"); query.setString("status", "purged"); int rowsCopied=query.executeUpdate(); ``` #### 1.4 HQL 選擇語句 HQL `SELECT`用于查詢數據庫中的類及其屬性。 這是`SELECT`語句的語法: ```java [SELECT [DISTINCT] property [, ...]] FROM path [[AS] alias] [, ...] [FETCH ALL PROPERTIES] WHERE logicalExpression GROUP BY property [, ...] HAVING logicalExpression ORDER BY property [ASC | DESC] [, ...] ``` 實體的標準名稱為`path`。 `alias`名稱可以用于縮寫對特定實體或其屬性的引用,并且在查詢中使用的屬性名稱不明確時,必須使用`alias`名稱。 `property`名稱是路徑中中列出的實體的屬性的名稱。 如果使用`*`**獲取所有屬性**,則將忽略延遲加載語義,并且將主動加載所有檢索到的對象的即時屬性(這不適用于遞歸) 。 `WHERE`用于使用`where`子句創建 **hql 選擇查詢**。 如果列出的屬性僅由`FROM`子句中的別名組成,則可以在 HQL 中省略`SELECT`子句。 如果我們將 JPA 與 JPQL 一起使用,則 HQL 和 JPQL 之間的區別之一是 JPQL 中需要`SELECT`子句。 ## 2\. HQL – `from`子句和別名 HQL 中要注意的最重要功能是**別名**。 Hibernate 允許我們使用`as`子句為查詢中的類分配別名。 使用別名引用回查詢中的類。 舉個例子: ```java from Product as p //or from Product as product ``` `as`關鍵字是可選的。 我們還可以在類名之后直接指定別名,如下所示: ```java from Product product ``` 如果我們需要完全限定 HQL 中的類名,只需指定包和類名即可。 Hibernate 將在后臺處理大部分此類操作,因此僅當我們的應用中具有重復名稱的類時,我們才真正需要這樣做。 如果我們必須在 Hibernate 中執行此操作,請使用如下語法: ```java from com.howtodoinjava.geo.usa.Product ``` `from`子句非常基礎,對于直接使用對象很有用。 但是,如果要使用對象的屬性而不將完整的對象加載到內存中,則必須使用`select`子句,如下一節所述。 ## 3\. HQL `select`子句和投影 與`from`子句相比,`select`子句對結果集的控制更多。 如果要獲取結果集中對象的屬性,請使用`select`子句。 例如,我們可以對僅返回名稱的數據庫產品進行投影查詢,而不是將整個對象加載到內存中,如下所示: ```java select product.name from Product product ``` 該查詢的結果集將包含一個 Java `String`對象列表。 此外,我們可以檢索數據庫中每種產品的價格和名稱,如下所示: ```java select product.name, product.price from Product product ``` 如果您只對一些屬性感興趣,則可以使用這種方法減少到數據庫服務器的網絡流量,并在應用的計算機上節省內存。 ## 4\. HQL 命名參數 Hibernate 在其 HQL 查詢中支持命名參數。 這使得編寫查詢以接受來自用戶的輸入的查詢變得容易,并且您不必防御 SQL 注入攻擊。 使用 JDBC 查詢參數時,無論何時添加,更改或刪除 SQL 語句的各個部分,都需要更新設置其參數的 Java 代碼,因為參數是根據它們在語句中出現的順序進行索引的。 Hibernate 允許您為 HQL 查詢中的參數提供名稱,因此您不必擔心在查詢中意外移動參數。 命名參數的最簡單示例對參數使用常規 SQL 類型: ```java String hql = "from Product where price > :price"; Query query = session.createQuery(hql); query.setDouble("price",25.0); List results = query.list(); ``` ## 5\. HQL – 對結果集分頁 通過數據庫查詢的結果集進行分頁是一種非常常見的應用模式。 通常,將分頁用于返回大量查詢數據的 Web 應用。 Web 應用將瀏覽數據庫查詢結果集以為用戶構建適當的頁面。 如果 Web 應用將每個用戶的所有數據都加載到內存中,則該應用將非常慢。 相反,您可以瀏覽結果集并檢索要一次顯示一個塊的結果。 查詢界面上有兩種分頁方法:`setFirstResult()`和`setMaxResults()`。 `setFirstResult()`方法采用一個代表結果集中第一行的整數,從第 0 行開始。您可以使用`setMaxResults()`方法告訴 Hibernate 僅檢索固定數量的對象。 您的 HQL 保持不變 - 您只需要修改執行查詢的 Java 代碼即可。 ```java Query query = session.createQuery("from Product"); query.setFirstResult(1); query.setMaxResults(2); List results = query.list(); displayProductsList(results); ``` 如果打開 SQL 日志記錄,則可以查看 Hibernate 用于分頁的 SQL 命令。 對于開源 HSQLDB 數據庫,Hibernate 使用`top`和`limit`。 Microsoft SQL Server 不支持`limit`命令,因此 Hibernate 僅使用`top`命令。 如果您的應用在分頁時遇到性能問題,這對于調試非常有用。 如果 HQL 結果集中只有一個結果,則 Hibernate 提供了一種僅獲取該對象的快捷方法,如下所述。 ## 6\. HQL – 獲得獨特的結果 HQL 的查詢界面提供了一種`uniqueResult()`方法,用于僅從 HQL 查詢中獲取一個對象。 盡管查詢可能只產生一個對象,但如果將結果限制為僅第一個結果,則也可以將`uniqueResult()`方法與其他結果集一起使用。 您可以使用上一節中討論的`setMaxResults()`方法。 `Query`對象上的`uniqueResult()`方法返回單個對象;如果結果為零,則返回`null`。 如果結果不止一個,則`uniqueResult()`方法將引發`NonUniqueResultException`。 ```java String hql = "from Product where price>25.0"; Query query = session.createQuery(hql); query.setMaxResults(1); Product product = (Product) query.uniqueResult(); ``` ## 7\. HQL – 使用`order by`子句對結果進行排序 要對 HQL 查詢的結果進行排序,您需要使用`order by`子句。 您可以按結果集中對象的任何屬性對結果進行排序:升序(`asc`)或降序(`desc`)。 如果需要,可以對查詢中的多個屬性使用排序。 用于排序結果的典型 HQL 查詢如下所示: ```java from Product p where p.price>25.0 order by p.price desc ``` 如果要按多個屬性進行排序,則只需將其他屬性添加到`order by`子句的末尾,并以逗號分隔。 例如,您可以按產品價格和供應商名稱進行排序,如下所示: ```java from Product p order by p.supplier.name asc, p.price asc ``` ## 8\. HQL 關聯 關聯使您可以在 HQL 查詢中使用一個以上的類,就像 SQL 允許您在關系數據庫中的表之間使用連接一樣。 您可以使用`join`子句向 HQL 查詢添加關聯。 Hibernate 支持五種不同類型的連接:內部連接,交叉連接,左外部連接,右外部連接和完全外部連接。 如果使用交叉連接,只需在`from`子句中指定兩個類(`from Product p, Supplier`)。 對于其他連接,請在`from`子句后使用`join`子句。 指定連接的類型,要連接的對象屬性以及其他類的別名。 您可以使用內部連接獲取每個產品的供應商,然后檢索供應商名稱,產品名稱和產品價格,如下所示: ```java select s.name, p.name, p.price from Product p inner join p.supplier as s ``` 您可以使用類似的語法檢索對象: ```java from Product p inner join p.supplier as s ``` ## 9,HQL 聚合方法 HQL 支持多種聚合方法,類似于 SQL。 它們在 HQL 中的工作方式與在 SQL 中的工作方式相同,因此您不必學習任何特定的 Hibernate 術語。 區別在于,在 HQL 中,聚合方法適用于持久對象的屬性。 您可以使用`count(*)`語法對結果集中的所有對象進行計數,或使用`count(product.name)`對具有`name`屬性的結果集中的對象數進行計數。 以下是使用`count(*)`方法對所有產品進行計數的示例: ```java select count(*) from Product product ``` 通過 HQL 可用的聚合功能包括: 1. `avg(property name)`:屬性值的平均值 2. `count(property name or *)`:結果中屬性出現的次數 3. `max(property name)`:屬性值的最大值 4. `min(property name)`:屬性值的最小值 5. `sum(property name)`:屬性值的總和 ## 10\. HQL 命名查詢 命名查詢是通過實體上的類級注解創建的; 通常,查詢適用于在其源文件中出現的實體,但是并沒有絕對的要求。 使用`@NamedQueries`注解創建命名查詢,該注解包含`@NamedQuery`集的數組; 每個都有一個查詢和一個名稱。 命名查詢的示例可能如下所示: ```java @NamedQueries({ @NamedQuery(name = "supplier.findAll", query = "from Supplier s"), @NamedQuery(name = "supplier.findByName", query = "from Supplier s where s.name=:name"), }) ``` 執行上述命名查詢更為簡單。 ```java Query query = session.getNamedQuery("supplier.findAll"); List<Supplier> suppliers = query.list(); ``` > 閱讀更多 – [Hiberate 命名查詢教程](//howtodoinjava.com/hibernate/hibernate-named-query-tutorial/ "named queries") ## 11\. HQL – 原生 SQL 盡管您應該盡可能使用 HQL,但是 Hibernate 確實提供了一種直接通過 Hibernate 使用本機 SQL 語句的方法。 使用本機 SQL 的原因之一是您的數據庫通過其 SQL 方言支持 HQL 中不支持的某些特殊功能。 另一個原因是您可能想從 Hibernate 應用中調用存儲過程。 您可以修改 SQL 語句,使其與 Hibernate 的 ORM 層一起使用。 您確實需要修改 SQL 以包括與對象或對象屬性相對應的 Hibernate 別名。 您可以使用`{objectname.*}`指定對象的所有屬性,也可以直接使用`{objectname.property}`指定別名。 Hibernate 使用這些映射將您的對象屬性名稱轉換為它們的基礎 SQL 列。 這可能不是您期望 Hibernate 正常工作的確切方式,因此請注意,您確實需要修改 SQL 語句以獲得完整的 ORM 支持。 您尤其會在帶有子類的類上遇到本機 SQL 的問題 - 確保您了解如何在單個表或多個表之間映射繼承,以便從表中選擇正確的屬性。 Hibernate 原生 SQL 支持的基礎是`org.hibernate.SQLQuery`接口,該接口擴展了`org.hibernate.Query`接口。 您的應用將使用`Session`接口上的`createSQLQuery()`方法從會話中創建本機 SQL 查詢。 ```java public SQLQuery createSQLQuery(String queryString) throws HibernateException ``` 將包含 SQL 查詢的字符串傳遞給`createSQLQuery()`方法后,應將 SQL 結果與現有的 Hibernate 實體,連接或標量結果相關聯。 `SQLQuery`接口具有`addEntity()`,`addJoin()`和`addScalar()`方法。 #### 11.1 Hibernate SQL 查詢示例 將本機 SQL 與標量結果一起使用是使用本機 SQL 入門的最簡單方法。 示例 Java 代碼如下所示: ```java String sql = "select avg(product.price) as avgPrice from Product product"; SQLQuery query = session.createSQLQuery(sql); query.addScalar("avgPrice",Hibernate.DOUBLE); List results = query.list(); ``` 返回上一對象結果集的**本機 SQL** 比上一個示例復雜一點。 在這種情況下,我們將需要將實體映射到 SQL 查詢。 ```java String sql = "select {supplier.*} from Supplier supplier"; SQLQuery query = session.createSQLQuery(sql); query.addEntity("supplier", Supplier.class); List results = query.list(); //Hibernate modifies the SQL and executes the following command against the database: select Supplier.id as id0_, Supplier.name as name2_0_ from Supplier supplier ``` ## 12\. HQL – 啟用日志和注解 Hibernate 可以將 HQL 查詢背后的基礎 SQL 輸出到應用的日志文件中。 如果 HQL 查詢未提供您期望的結果,或者查詢花費的時間比您想要的長,則此功能特別有用。 這不是您必須經常使用的功能,但是在您必須向數據庫管理員尋求幫助來調整 Hibernate 應用時,此功能很有用。 #### 12.1 HQL 日志 查看 Hibernate HQL 查詢的 SQL 的最簡單方法是使用“`show_sql`”屬性在日志中啟用 SQL 輸出。 在`hibernate.cfg.xml`配置文件中將此屬性設置為`true`,Hibernate 會將 SQL 輸出到日志中。 當您在應用的輸出中查找 Hibernate SQL 語句時,它們的前綴將為“`Hibernate:`”。 如果您將 log4j 日志記錄為 Hibernate 類進行調試,則您將在日志文件中看到 SQL 語句,以及有關 Hibernate 如何解析 HQL 查詢并將其轉換為 SQL 的大量信息。 #### 12.2 HQL 注解 跟蹤 HQL 語句到生成的 SQL 可能很困難,因此 Hibernate 在`Query`對象上提供了注解功能,使您可以將注解應用于特定查詢。 `Query`接口具有`setComment()`方法,該方法將`String`對象作為參數,如下所示: ```java public Query setComment(String comment) ``` 即使沒有使用`setComment()`方法,Hibernate 也不會在沒有其他配置的情況下將注解添加到 SQL 語句中。 您還需要在 Hibernate 配置中將 Hibernate 屬性`hibernate.use_sql_comments`設置為`true`。 如果您設置了此屬性,但沒有以編程方式在查詢中設置注解,則 Hibernate 將在注解中包括用于生成 SQL 調用的 HQL。 我發現這對于調試 HQL 非常有用。 如果啟用了 SQL 日志記錄,請使用注解來標識應用日志中的 SQL 輸出。 目前,這一切都與 **HQL 教程**有關。 繼續訪問以了解更多有關 Hiberate 的信息。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看