Hibernate 提供 createSQLQuery(String sql) 執行原生 SQL,適用於複雜查詢、存儲過程、或效能調優場景。
Query query = session.createSQLQuery("SELECT * FROM t_user");
List
// 別名查詢: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 別名佔位符,會自動展開為映射文件定義的所有列。
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);
Query query = session.createSQLQuery("SELECT * FROM t_user")
.addEntity(User.class); // 不需別名
將 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 優化。
在映射文件 <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 ...} 語法。
CONNECT BY)使用原生 SQL。