Hibernate中的1+N問題(帶級聯查詢條件的情況)


1. Hibernate中的1+N問題描述   

        在多對一關系中,當我們需要查詢多的一方對應的表的記錄時,可以用一條sql語句就能完成操作。然而,在多的一方的實體類中的@ManyToOne標注的fetch的默認值是fetchType.EAGER,這時,hibernate除了發出查詢多的一方對應的表的記錄的sql語句外,還會發出n(多方記錄數)條sql語句,這就是1+n問題。如:bbs的板塊(Category),主題(topic),回復(msg)。一個板塊有多個主題,而一個主題屬於一個板塊,則Category和topic屬於一對多的關系,在topic里設置@ManyToOne。當需要取出所有的主題時,只需要發出select * from topic一條語句就能做到。然而,hibernate會查詢出每個topic所對應的Category,所以會發出1+n條sql語句。

2. 1+N問題的解決辦法

    ①設置@ManyToOne的fetch屬性值為fetchType.LAZY,這種方式解決后,后面的n條sql語句按需而發。但是有個弊端,就是如果需要級聯查詢就無法獲取級聯對象了。

    ②設置@BatchSize(size=5)(該注解要加在類上面,跟@Entity在同一位置),這樣發出的sql語句減少。這個設置在一定程度上提高了效率。

    ③在hqp語句中使用用join fetch,事實上Criteria用的就是這種方法。這也是最常用的方法;

[java] view plain copy 在CODE上查看代碼片派生到我的代碼片
  1. @Test   
  2. //join fetch  
  3. publicvoid test1_N3(){  
  4.     Session session=sf.getCurrentSession();  
  5.     session.beginTransaction();  
  6.     //List<Topic> topics=(List<Topic>)session.createCriteria(Topic.class).list();//只有一條查詢語句,Criteria方法就是這種方式  
  7.     List<Topic> topics=(List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();  
  8.     for (Topic t:topics) {  
  9.         System.out.println(t.getId()+"----"+t.getTitle());  
  10.         System.out.println(t.getCategory().getName());  
  11.     }  
  12.     session.getTransaction().commit();  
  13. }  

 3: 注:上面的就是最簡單的1+n問題了

本人在項目中遇到過更加復雜的1+n問題。當帶條件查詢的時候:

如果我有查詢條件呢?用left join fetch要報錯

比如下面這個查詢

from Topic t left join fetch t.category c where t.c.id='id' 會報錯

from Topic t where t.c.id='id' 不會報錯,但是有1+n問題。

目前我還沒有找到辦法解決這個問題,找到解決辦法了,會更新文章的。

如果我有查詢條件呢?用left join fetch要報錯
比如下面這個查詢
from Topic t left join fetch t.category c where t.c.id='id' 會報錯
from Topic t where t.c.id='id' 不會報錯,但是有1+n問題。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com