Hibernate之一级缓存和N+1问题

1.

Listls = session.createQuery("fromStudent").setFirstResult(0).setMaxResults(50).list();Iteratorstus = ls.iterator();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

此时会发出一条sql取出所有的学生信息

2.

Iterator stus = session.createQuery("from Student").setFirstResult(0).setMaxResults(50).iterate();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

如果使用iterator方法返回列表,对于hibernate而言,它仅仅只是 发出取id列表的sql

在查询相应的具体的某个学生信息时,会发出相应的SQL去取学生信息

 这就是典型的N+1问题

存在iterator的原因是,有可能会在一个session中查询两次数据,如果使用list每一次都会把所有的对象查询上来

而是要iterator仅仅只会查询id,此时所有的对象已经存储在一级缓存(session的缓存)中,可以直接获取

3.

Listls = session.createQuery("fromStudent").setFirstResult(0).setMaxResults(50).list();

Iteratorstus = ls.iterator();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

此时会发出一条sql取出所有的学生信息

stus = session.createQuery("from Student").setFirstResult(0).setMaxResults(50).iterate();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

使用iterate仅仅只会去查Student的id,此时Student的数据已经在缓存中,所以不会在出现N+1.

4

Listls=session.createQuery("fromStudent").setFirstResult(0).setMaxResults(50).list();

Iteratorstus = ls.iterator();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

此时会发出一条sql取出所有的学生信息

ls = session.createQuery("from Student").setFirstResult(0).setMaxResults(50).list();

stus = ls.iterator();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

会发出SQL取完整的学生对象,占用内存相对较多.

5.

Listls = session.createQuery("fromStudent").setFirstResult(0).setMaxResults(50).list();

Iteratorstus = ls.iterator();

for(;stus.hasNext();) {

Student stu = stus.next();

System.out.println(stu.getName());}

//id=1的Student对象已经在session的缓存(一级缓存)中,此时就不会发sql去取Student

Student stu = (Student)session.load(Student.class, 1);

System.out.println(stu.getName()+",---");

注意:一级缓存是指session一关闭就会消失的缓存。

你可能感兴趣的:(Hibernate之一级缓存和N+1问题)