hibernate缓存

我们经常用到查询功能,所以拿Query接口中的list()和iterator()方法讲解:也就是著名的“N+1”问题。
我们经常习惯于这样的查询语句:
Query query=session.createQuery("from Students");
List<Students> students=query.list();
for(Iterator<Students> iter=students.iterator();iter.hasNext();)
{
    .............
}
当我们使用list()方法时,相当于发出了这样一条sql语句:select * from students;
查询出所有的students数据。
同时我们看一下iterator()方法的使用:
Query query=session.createQuery("from Students");
Iterator<Students> iter=query.iterator();
while(iter.hasNext())
{
   ............
}
Hibernate这时会发出一条查询所有id集合的语句,相当于这样一条sql:
select id from students;
这时Hibernate得到一个包含表中所有id的集合,比如说:Set<Integer> id;这样的东西,
然后Hibernate会拿出id集合中的每个值,同session缓存(即一级缓存,Hibernate中用两个级别的
缓存。)中的id值一一对比,如果有了该id的值,就不会发sql语句,而是直接使用session缓存中早
先存放的数据。否则的话,Hibernate会分别发出一条语句,类似于这样的sql语句:
select * from students where id=?;如果表中有N条记录,则Hibernate会发出N条查询语句。
这就是“N+1”问题。这就说明了iterator()方法是使用缓存的。
如果我们先写一条使用list()查询的语句,然后紧跟着用iterator()方法再一次查找的话,
list()方法会发出sql语句查找数据表中的所有数据,当我们再次使用iterator()方法查找时,
由于先前使用list()方法将所有数据都查找出来,并写入了session的缓存,所以,
iterator()方法查询时只需要使用1条语句,查找到所有的id集合即可,然后和session缓存中的
值一一对应,由于全部都早已由list()方法放入了。所以后面的N条语句就不会发了。
总结:iterator()使用缓存,而list()放入缓存。

相关推荐