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的内容:
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





这里先看一下doc里面对iterate的说明

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[].

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



也就是说, 返回的对象是按需初始化, 第一个sql查询只返回identifiers,在这里就是ID。
Hibernate: select user0_. id 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语句来获取该对象的属性值。

猜你喜欢

转载自alleni123.iteye.com/blog/1975094
今日推荐