首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Hibernate 延遲加載優化:lazy=true 避免主表查詢時無用關聯查詢

     編輯:MySQL 資料庫相關知識

Hibernate 延遲加載實戰:一張映射文件看懂 lazy 屬性

Hibernate 中 lazy 屬性控制關聯對象的加載策略。正確配置能顯著減少無效查詢,提升效能。本文以實際映射文件為例,解析 lazy="true" 的作用機制與最佳實踐。

一、映射文件範例

<hibernate-mapping>
  <class name="com.pojo.Sortp" table="sortp" catalog="shjdc">
    <id name="id" type="java.lang.Integer">
      <column name="Id" />
      <generator class="assigned" />
    </id>
    <property name="name" type="java.lang.String">
      <column name="Name" length="40" not-null="true" />
    </property>

    <!-- 關鍵配置:lazy="true" -->
    <set name="productses" inverse="true" cascade="all" lazy="true">
      <key>
        <column name="Sortid" not-null="true" />
      </key>
      <one-to-many class="com.pojo.Products" />
    </set>
  </class>
</hibernate-mapping>

二、lazy 屬性核心差異

設置行為SQL 執行時機適用場景
lazy="true" (默認)延遲加載:首次訪問集合時發起查詢調用 sortp.getProductses() 時大多數一對多、多對多關聯;不確定是否會用到子表數據
lazy="false"立即加載:查詢主表時同時 JOIN 子表執行 from Sortp 時確定每次查主表必須用到子表數據(極少見)
lazy="extra"極度延遲:size()、contains() 不加載全集合調用 iterator() 時超大集合,僅需統計數量或判斷包含

三、實戰效能對比

-- lazy="false":無論是否用到 products,均執行
SELECT s.*, p.* FROM sortp s LEFT JOIN products p ON s.Id = p.Sortid;

-- lazy="true":僅查主表
SELECT * FROM sortp;
-- 後續調用 getProductses() 時才執行
SELECT * FROM products WHERE Sortid = ?;

結論: 除非業務100% 確定每次查主表必用子表,否則堅持 lazy="true"。盲目關閉延遲加載會產生大量無用 JOIN,拖慢主表查詢、增加網路傳輸、消耗記憶體。

四、常見陷阱與對策

  1. Session 關閉後訪問懶加載屬性 → LazyInitializationException
    • 方案 A:Open Session In View 模式(Web 過濾器延長 Session 生命周期)
    • 方案 B:DTO 投影查詢,Service 層組裝所需數據,避免 View 層觸發懶加載
    • 方案 C:Hibernate.initialize(proxy) 在 Session 開啟時顯式初始化
  2. N+1 問題:遍歷列表逐個訪問懶加載集合 → 產生 N 條額外 SQL。
    • 方案:HQL/JPA JOIN FETCH 或 @EntityGraph 批量預加載。
  3. 二級緩存配合:啟用集合緩存 <cache usage="read-write"/>,減少重複懶加載查詢。

五、註解配置對應

@OneToMany(mappedBy = "sortp", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<Products> productses = new HashSet<>();
// fetch = FetchType.LAZY 對應 lazy="true"
// FetchType.EAGER 對應 lazy="false"
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved