Query.list() 与 Query.iterator() 区别

iterator()方法的出现主要是为了解决查询是的性能问题。例如下面使用list()方法取得对象的代码:
........//打开Session,开启事务
Query q = session.createQuery("from Student");
//以下为查询在name中"t"字符的所以学生
q = session.createQuery("from Student s where s.name like 't%'");
q.list();
........//提交事务,关闭 session
运行以上代码,得到的控制台信息如下:
Hibernate : select s.* from student s
Hibernate : select s.* from student s where s.name like 't%'
  第2条select 语句查找所以匹配条件的对象,然后根据起id值到Session缓寸中查找这个对象是否已经存在,如果已经存在,则返回缓存中这个对象的引用,不再重新组装对象。因此select * 是不必要的,只需要select s.id 即可。
  Query接口的iterator()方法发送select 语句检索id字段,然后根据id 值在Session缓存和二级缓存中查找匹配的对象,如果存在,把它直接加到查询结果返回,如果不存在,根据刚才已经检索出来的id,执行额外的 select语句到数据库检索该对象。
  Student表中共有两个Student对象,首先通过get()方法把一个Student对象加载到 Session缓存,然后再查询所有的Student对象,观察控制台的输出语句,如下代码所示:
.....//打开session,开启事务
stu = (Student) session.get(Student.class , new Integer(1));
Query q = session.createQuery("from Studnet");
Iterator it = q.iterator();
stu1 = (Student) it.next();
stu2 = (Student) it.next();
........//提交事务,关闭 session
运行以上代码,得到的控制台信息如下:
Hibernate : select s.* from student s where s.id = ?
Hibernate : select s.id from student s
Hibernate : select s.* from student s where s.id = ?
  第1条select * 语句是由get()方法引起的,第2条select s.id 是由q.iterator()引起的(如果调用集合对象的iterator()方法,将会发送select * from table,比如team.getStudent().iterator()),第3条语句是因为在缓存中只存在一个Student对象,还有一个 Student对象必须发送SQL语句从数据库取得,然后再把它加入到session缓存中。
  Query接口的iterator()方法和load()方法很相似,只不过load()用于加载单独的对象,而iterator()用于批量的加载。某 些情况下, 可以使用iterator()获得更好的性能。这通常用于预期返回的结果在Session,或二级缓存中(second-level cache)中已经存在时的情况。当缓存中的对象很少,或者iterator()查询的范围过于宽广时(比如HQL语句"from Student"),反而对性能造成不利的影响,因为iterator()方法第一次总是查询所有的id,然后根据id值一条一条地发送select 语句去取得对象,因此如果有有10000条记录,而且是在Session中是第一次查询时(缓存中还没有对象数据),则要发送10001条SQL语句去取 得数据,这样的话,还不如直接用以下语句来得方便高效。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝翔招生办

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值