解決JPA 和Hibernate 中的N 1 查詢問題
當查詢擷取N 筆記錄並且後續查詢取得相關記錄時,就會出現N 1 問題記錄,導致額外的N 次查詢。當在初始查詢期間未取得關聯時,在 Hibernate 中可能會發生這種情況。
因果關係
為了說明這一點,請考慮以下檢索PostComment 實體的JPA 查詢:
List<PostComment> comments = entityManager.createQuery("select pc from PostComment pc where pc.review = :review", PostComment.class) .setParameter("review", review) .getResultList();
如果我們隨後迭代評論並存取貼文關聯,Hibernate 將發出以下SQL語句:
SELECT pc.id AS id1_1_, pc.post_id AS post_id3_1_, pc.review AS review2_1_ FROM post_comment pc WHERE pc.review = 'Excellent!' INFO - Loaded 3 comments SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 1 INFO - The post title is 'Post nr. 1' SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 2 INFO - The post title is 'Post nr. 2' SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 3 INFO - The post title is 'Post nr. 3'
這裡,執行三個附加查詢以取得每個Comment 的Post 實體。這是 N 1 查詢問題。
解決方案
為了解決這個問題,我們可以使用JOIN FETCH 關鍵字急切地獲取所需的關聯:
List<PostComment> comments = entityManager.createQuery("select pc from PostComment pc join fetch pc.post p where pc.review = :review", PostComment.class) .setParameter("review", review) .getResultList();
對於多個子關聯,建議在初始查詢中取得一個集合,並透過輔助查詢載入其餘集合
自動偵測
要偵測N 1 問題,使用SQL 日誌記錄和斷言實施整合測試以驗證產生的SQL 語句的預期數量是有益的。 db-util 等工具可以幫助完成此過程。
以上是如何解決 JPA 和 Hibernate 中的 N 1 查詢問題?的詳細內容。更多資訊請關注PHP中文網其他相關文章!