hibernate:1+N问题
Hibernate中常会用到set,bag等集合表示1对多的关系,在获取实体的时候就能根据关系将关联的对象或者对象集取出,还可以设定cacade进行关联更新和删除。这不得部说hibernate的orm做得很好,很贴近oo的使用习惯了。
但是对数据库访问还是必须考虑性能问题的,在设定了1对多这种关系之后,查询就会出现传说中的n+1问题。
1)1对多,在1方,查找得到了n个对象,那么又需要将n个对象关联的集合取出,于是本来的一条sql查询变成了n+1条
2)多对1,在多方,查询得到了m个对象,那么也会将m个对象对应的1方的对象取出,也变成了m+1
怎么解决n+1问题?
1)lazy=true,hibernate3开始已经默认是lazy=true了;lazy=true时不会立刻查询关联对象,只有当需要关联对象(访问其属性,非id字段)时才会发生查询动作。
2)二级缓存,在对象更新,删除,添加相对于查询要少得多时,二级缓存的应用将不怕n+1问题,因为即使第一次查询很慢,之后直接缓存命中也是很快的。
不同解决方法,不同的思路,第二条却刚好又利用了n+1。
-----------------------------------------------
Hibernate的两个类设置了manyToOne之后,在查询的时候,由于N对1的一方默认的fetch=FetchType.EAGER,所以会把被关联的对象一起取出来
解决方法一:设置fetch=FetchType.LAZY
解决方法二:
//List<Student>students=(List<Student>)session.createCriteria(Student.class).list();
List<Student>students=(List<Student>)session.createQuery("fromStudent").list();
也就是用session.createCriteria()做查询,而不是用createQuery