Query的iterator初步学习笔记

出自圣思院hibernate14讲 [Query接口的list与iterator方法深度解析与延迟加载详析]

	Query query=session.createQuery("from User");

Iterator<User> iter=query.iterate();

while(iter.hasNext()){
System.out.println(iter.next());
}


以上代码在运行时, 会出现一个有意思的现象 ,就是程序像数据库发送了N条select语句。(跟数据库里存在的数据量一样)

附上console的内容:
[color=red]Hibernate: select user0_.id as col_0_0_ from test_user user0_
Hibernate: select user0_.id as id1_1_0_, user0_.test_name as test2_1_0_ from test_user user0_ where user0_.id=?
com.lj.zhang.User@4406cef4
Hibernate: select user0_.id as id1_1_0_, user0_.test_name as test2_1_0_ from test_user user0_ where user0_.id=?
com.lj.zhang.User@1d716fa0[/color]


这里先看一下doc里面对iterate的说明
[color=blue]
Iterator iterate() throws HibernateException

Return the query results as an Iterator. If the query contains multiple results pre row, the results are returned in an instance of Object[].

[b]Entities returned as results are initialized on demand. The first SQL query returns identifiers only.[/b]
Returns:
the result iterator[/color]


也就是说, 返回的对象是按需初始化, 第一个sql查询只返回identifiers,在这里就是ID。
Hibernate: select user0_.[b]id[/b] as col_0_0_ from test_user user0_
这句被执行的地方在
Iterator<User> iter=query.iterate();

---------再看一下最常用的list方法说明
Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].
这里获取的row就直接被封装到Object[]里面,然后返回。


用一个删除的例子来说明两者的区别.


	Query query = session.createQuery("from User");

Iterator<User> iter = query.iterate();


while (iter.hasNext())
{
session.delete(iter.next());
}

这个例子会产生大量的select语句, 因为每次执行delete的时候, 都要从数据库读取一个对象。

而换成

 List<User> list=query.list();

Iterator listIter=list.iterator();
while(listIter.hasNext()){
session.delete(listIter.next());
}

就只会产生一个select语句, 这样就节约了开支。


----------再用一个读取的例子看一下-------------
		Session session = HibernateUtil.openSession();

Transaction tx = null;

tx = session.beginTransaction();

Query query = session.createQuery("from User");


List<User> list=query.list();
// Iterator it=query.iterate();


tx.commit();

[b]session.close();[/b]

for(User u:list){
System.out.println(u.getName());
}

// while(it.hasNext()){
// System.out.println(((User)it.next()).getName());
// }

这里加入了session.close(),
通过list()方法会正常运行。
但是iterator() 方法就会出错, 因为session已经被关闭。而iterator在被调用的时候则需要再次发送sql语句, 但是已经找不到session了。


=============总结=============
Query接口的list()方法和iterator()方法都可以实现获取查询的对象, 但是list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了), 而iterator()方法所返回的对象中仅包含了主键值(标识符), 只有对iterator()中的对象进行操作时, hibernate才会向数据库再次发生SQL语句来获取该对象的属性值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值