我们经常用到查询功能,所以拿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()放入缓存。
hibernate缓存
最新推荐文章于 2024-07-03 08:47:24 发布