在多对一关系中,当我们需要查询多的一方对应的表的记录时,可以用一条sql语句就能完成操作。然而,在多的一方的实体类中的@ManyToOne标注的fetch的默认值是eager,这时,hibernate除了发出查询多的一方对应的表的记录的sql语句外,还会发出n(多方记录数)条sql语句,这就是1+n问题。如:bbs的板块(Category),主题(topic),回复(msg)。一个板块有多个主题,而一个主题属于一个板块,则Category和topic属于一对多的关系,在topic里设置@ManyToOne。当需要取出所有的主题时,只需要发出select * from topic一条语句就能做到。然而,hibernate会查询出每个topic所对应的Category,所以会发出1+n条sql语句。
解决的方法是:①设置@ManyToOne的fetch属性值为lasy,这种方式解决后,后面的n条sql语句按需而发。
②设置@BatchSize(size=5),这样发出的sql语句减少。这个设置在一定程度上提高了效率。
③用join fetch,事实上Criteria用的就是这种方法。
//join fetch
@Test
publicvoid test1_N3(){
Session session=sf.getCurrentSession();
session.beginTransaction();
//List<Topic> topics=(List<Topic>)session.createCriteria(Topic.class).list();
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();
}