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

Hibernate 註解定義命名查詢與原生 SQL 映射詳解

     編輯:J2EE

前言

Hibernate 允許在實體類別上以註解方式預先定義靜態查詢 (Named Query) 與原生 SQL 查詢 (Named Native Query),這些查詢在 SessionFactory 建立時即被解析並載入記憶體,全系統可重複使用,提升維護性與效能。

HQL/JPQL 命名查詢 (@NamedQuery)

單一查詢定義

@Entity
@NamedQueries({
    @NamedQuery(name = "query1", query = "select a from A a")
})
public class A { ... }

多查詢與參數綁定

@Entity
@NamedQueries({
    @NamedQuery(name = "query1", query = "select c from A c where c.id = :id"),
    @NamedQuery(name = "query2", query = "select c from C c where c.id = :id")
})
public class A { ... }

進階 Hint 設定

透過 hints 屬性可指定查詢行為:

@NamedQuery(
    name = "query2",
    query = "select c from A c where c.id = ?",
    hints = @QueryHint(name = "timeout", value = "20")
)

常用 Hint 參數:

參數名說明預設值
cacheable是否啟用二級緩存false
cacheRegion指定緩存區域名稱otherwise
timeout查詢超時秒數-
fetchSizeJDBC 抓取筆數-
flushMode刷新模式-
cacheMode緩存模式-
readOnly載入實體設為唯讀false
commentSQL 註釋-

呼叫方式

Query q = session.getNamedQuery("query1");
q.setParameter("id", 123);
List list = q.list();

原生 SQL 查詢 (@NamedNativeQuery + @SqlResultSetMapping)

基本映射整個實體

@Entity
@NamedNativeQueries({
    @NamedNativeQuery(
        name = "nativesql1",
        query = "select * from b where id > 1",
        resultSetMapping = "sql1mapping"
    )
})
@SqlResultSetMappings({
    @SqlResultSetMapping(
        name = "sql1mapping",
        entities = @EntityResult(entityClass = B.class)
    )
})
public class B { ... }

僅映射特定欄位

使用 fields 屬性指定欄位對應:

@Entity
@NamedNativeQueries({
    @NamedNativeQuery(
        name = "nativesql1",
        query = "select bname from b where id > 1",
        resultSetMapping = "sql1mapping"
    )
})
@SqlResultSetMappings({
    @SqlResultSetMapping(
        name = "sql1mapping",
        entities = @EntityResult(
            entityClass = B.class,
            fields = @FieldResult(name = "bname", column = "bname")
        )
    )
})
public class B { ... }

呼叫與注意事項

Query q = session.getNamedQuery("nativesql1");
List list = q.list();
for (B b : list) {
    System.out.println(b.getBname()); // 正常
    // System.out.println(b.getId()); // 拋出異常:Column 'id1_0_' not found
}

關鍵提醒: 若 ResultSetMapping 僅包含部分欄位,實體中未映射的欄位 (如 id) 存取時將拋出異常,建議查詢時包含主鍵或使用 DTO 承接。

總結

善用 @NamedQuery 與 @NamedNativeQuery 可將查詢邏輯集中管理,配合 Hint 微調行為,並透過 @SqlResultSetMapping 靈活處理原生 SQL 結果映射,是大型專案優化資料存取層的關鍵技巧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved