前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
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用的就是這種方法。這也是最常用的方法;
@Test
//join fetch
publicvoid test1_N3(){ Session session=sf.getCurrentSession(); session.beginTransaction(); //List<Topic> topics=(List<Topic>)session.createCriteria(Topic.class).list();//只有一條查詢語句,Criteria方法就是這種方式 List<Topic> topics=(List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list(); for (Topic t:topics) { System.out.println(t.getId()+"----"+t.getTitle()); System.out.println(t.getCategory().getName()); } session.getTransaction().commit();
}
這就是Hibernate中的1+N問題,如有錯誤之處,歡迎留言指正~