1. hibernate3 中的 list()和iterate()的区别
list()是通过一条SELECT SQL语句实现查询操作;而iterate()则是N+1次的SELECT SQL语句实现查询操作,第一次它获取了所有的ID,然后再依次查询byID.
这其中涉及到hibernate的缓存机制.
list()查询是将符合条件的记录都查询出来,并将实体对象缓存在缓存中.
而iterator在查询时先将符合条件的记录的ID查询出来,并依次按这些ID在缓存中查询记录,如若有符合条件的实体对象则返回,如缓存中没有记录,再执行SELECT SQL BY ID去查询相应的记录.
Query query=seesion.createQuery("from User user where id<55"); Iterator<User> list4=query.iterate(); while(list4.hasNext()) { User user=list4.next(); System.out.println(user.getId()+"_"+user.getUsername()+"_"+user.getPwd()); } List li=query.list(); Iterator<User> list=li.iterator(); while(list.hasNext()) { User user=list.next(); System.out.println(user.getId()+"_"+user.getUsername()+"_"+user.getPwd()); } List li2=query.list(); Iterator<User> list2=li2.iterator(); while(list2.hasNext()) { User user=list2.next(); System.out.println(user.getId()+"_"+user.getUsername()+"_"+user.getPwd()); } Iterator<User> list3=query.iterate(); while(list3.hasNext()) { User user=list3.next(); System.out.println(user.getId()+"_"+user.getUsername()+"_"+user.getPwd()); }
Hibernate: select user0_.id as x0_0_ from user user0_ where (id<55 ) Hibernate: select user0_.id as id0_, user0_.username as username0_, user0_.pwd as pwd0_ from user user0_ where user0_.id=? Hibernate: select user0_.id as id0_, user0_.username as username0_, user0_.pwd as pwd0_ from user user0_ where user0_.id=? 52_1111111_1111111 53_99999999_1111111111 Hibernate: select user0_.id as id, user0_.username as username, user0_.pwd as pwd from user user0_ where (id<55 ) 52_1111111_1111111 53_99999999_1111111111 Hibernate: select user0_.id as id, user0_.username as username, user0_.pwd as pwd from user user0_ where (id<55 ) 52_1111111_1111111 53_99999999_1111111111 Hibernate: select user0_.id as x0_0_ from user user0_ where (id<55 ) 52_1111111_1111111 53_99999999_1111111111
第一次iterate()查询,由于没有缓存符合条件的实体对象,依次按ID执行SELECT SQL查询操作
第二次list()查询,执行SELECT SQL查询操作
第三次list()查询,执行SELECT SQL查询操作(为何没有使用缓存中的实体对象呢,因为查询需要查找到所有符合条件的记录,因此必须执行SELECT SQL,来保证查询数据的完整性;而iterate()通过执行SELECT SQL语句来获取满足查询条件的记录的ID,来保证查询数据的完整性).
第四次iterate()查询,由于有缓存符合条件的实体对象,依次按ID在缓存中查询.
可以说list()实际上不利用缓存,对缓存只写不读。而iterate()可以充分利用缓存,提高那些频繁读取的查询操作,提高性能。
一般如果是查询数据量足够大,如10W条,则可通过session.evict(user)和sessionFactory.evict(user)来达到清除缓存的操作,即每次查询某条记录之后,跟上上述操作,可不将实体对象缓存。