首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 原生 SQL 查詢與自定義 DML 完整指南

     編輯:Java 相關知識

核心 API:Session.createSQLQuery()

Hibernate 提供 createSQLQuery(String sql) 執行原生 SQL,適用於複雜查詢、存儲過程、或效能調優場景。


一、基本查詢與結果映射

1. 純標量查詢:返回 Object[] 陣列

Query query = session.createSQLQuery("SELECT * FROM t_user");
List rows = query.list();
for (Object[] row : rows) {
    Long id = (Long) row[0];
    String name = (String) row[1];
    Integer age = (Integer) row[2];
}

2. 實體映射:addEntity() 返回受管理實體

// 別名查詢:SELECT {usr.*} 對應映射文件定義的列
Query query = session.createSQLQuery("SELECT {usr.*} FROM t_user usr")
                     .addEntity("usr", User.class); // 別名 usr 對應 User 映射
List users = query.list(); // 返回持久化 User 物件

關鍵點:{usr.*} 是 Hibernate 別名佔位符,會自動展開為映射文件定義的所有列。

3. 部分列映射:指定列別名

Query query = session.createSQLQuery(
    "SELECT u.id AS {usr.id}, u.name AS {usr.name}, u.age AS {usr.age} FROM t_user u"
).addEntity("usr", User.class);

4. 無別名表:直接指定實體類

Query query = session.createSQLQuery("SELECT * FROM t_user")
                     .addEntity(User.class); // 不需別名

二、命名查詢:XML 配置 SQL

將 SQL 移至映射文件(.hbm.xml),實現 SQL 與代碼分離。

<sql-query name="queryUserByName">
    <return alias="usr" entity-name="com.example.User"/>
    SELECT {usr.*} FROM t_user usr WHERE name = :name
</sql-query>

代碼調用:

Query query = session.getNamedQuery("queryUserByName");
query.setParameter("name", "shun");
List users = query.list(); // 無需 addEntity,XML 已配置映射

優勢:SQL 集中維護、可預編譯、支援 DBA 優化。


三、自定義 DML:sql-insert、sql-update、sql-delete

在映射文件 <class> 內部覆蓋預設的 INSERT/UPDATE/DELETE 語句。

<class name="User" table="t_user">
    <id name="id" column="user_id"><generator class="native"/></id>
    <property name="name" column="user_name"/>
    <property name="age" column="age"/>
    
    <!-- 自定義 INSERT -->
    <sql-insert>
        INSERT INTO t_user (user_name, age) VALUES (?, ?)
    </sql-insert>
    
    <!-- 自定義 UPDATE -->
    <sql-update>
        UPDATE t_user SET user_name=?, age=? WHERE user_id=?
    </sql-update>
    
    <!-- 自定義 DELETE -->
    <sql-delete>
        DELETE FROM t_user WHERE user_id=?
    </sql-delete>
</class>

參數綁定順序:屬性順序(不含 ID)+ ID。Hibernate 自動按映射順序綁定 ? 佔位符。


四、存儲過程調用

<sql-query name="callProc" callable="true">
    <return alias="usr" entity-name="com.example.User"/>
    {CALL get_user_by_id(?)}
</sql-query>

設置 callable="true" 告知 Hibernate 使用 JDBC {CALL ...} 語法。


最佳實踐建議

  1. 優先使用 HQL/JPQL,原生 SQL 破壞資料庫可移植性。
  2. 複雜報表、大數據分頁、特定資料庫函數(如 Oracle CONNECT BY)使用原生 SQL。
  3. 命名查詢集中管理 SQL,便於 DBA 調優。
  4. 自定義 DML 慎用,僅用於特殊表結構(如視圖、觸發器、分區表)。
  5. 原生 SQL 查詢返回實體時,必須包含所有映射列(含 ID、版本、關聯外鍵),否則實體狀態不完整。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved