Home>Article>Database> Hibernate 中Query的list方法和iterator方法

Hibernate 中Query的list方法和iterator方法

WBOY
WBOY Original
2016-06-07 17:09:59 1074browse

Hibernate中用hql通过query进行查询的时候,通常会用list或者Iterator取得查询到的结果.在此简单说明一下这两个方法的不同之处和适

Hibernate中用hql通过query进行查询的时候,通常会用list或者Iterator取得查询到的结果.在此简单说明一下这两个方法的不同之处和适用场景.

List:查询到的结果会被完整地放进内存(session的缓存),实体会处于持久状态.如果用迫切连接(fetch)模式,取得的结果可能会存在主表对应的一条记录会在list里存在多个实例(准确的讲是实例引用),多次出现但是指向同一个对象.list只会执行一条SQL语句.

Iterator:会在第一次把所有的id查询出来,然后在真正Iterator的时候,根据session的缓存中是否存在对应的对象而决定是否上数据库查询.如果session的缓存中不存在,通常会产生1+N次SQL查询.

list example:

s1 = sessionFactory.openSession();
Query q = s1.createQuery("from com.test.hb.Hbtest h where h.idList l = q.list();
Iterator itr = l.iterator();
while(itr.hasNext()){
Hbtest tbo = (Hbtest)itr.next();

1条SQL:

select hbtest0_.ID as ID0_,hbtest0_.VAL as VAL0_ from HB.HBTEST hbtest0_ where hbtest0_.ID

Iterator example:

s1 = sessionFactory.openSession();
Query q = s1.createQuery("from com.test.hb.Hbtest h where h.idIterator itr = q.Iterator();
while(itr.hasNext()){
Hbtest tbo = (Hbtest)itr.next();

3条SQL(1+2)

第一条SQL取得id

select hbtest0_.ID as col_0_0_ from HB.HBTEST hbtest0_ where hbtest0_.ID

两条根据id取记录的SQL(缓存中不存在于该id对应的记录)

select hbtest0_.ID as ID0_0_, hbtest0_.VAL as VAL0_0_ from HB.HBTEST hbtest0_ where hbtest0_.ID=?

使用场景:如果在cache中不存在对应的记录时,用list方法.如果大量的记录已经在cache中存在,用Iterator性能更好.

query 的cache打开后对list和iterator方式的影响:

将query 的cache打开的话,缓存的是query本身,以,,再加上参数,分页等信息做为key值,而不是query的结果.query的结果是放在session的cache中,和query的cache是有区别的.

打开query的cache:1,在config中设置 hibernate.cache.use_query_cache = true,2,在创建query后query.setCacheable(true);

下面是打开query的cache后用list的几个场景:

1:

Query q1 = s1.createQuery("from com.test.hb.Hbtest h where h.id

q1.setCacheable(true);

Query q2 = s1.createQuery("from com.test.hb.Hbtest h where h.id=1");
q2.setCacheable(true);

从逻辑上将,第一个query查询出的值应该包含第二个query,但是第二个query不会用query的cache,而是会从新查询数据库.

2:

Query q1 = s1.createQuery("from com.test.hb.Hbtest h where h.id=1");

q1.setCacheable(true);

Query q2 = s1.createQuery("from com.test.hb.Hbtest h where h.id=1");
q2.setCacheable(true);

两个query一模一样,第二个query会用query的cache,不会从新查询数据库.

3:

Query q1 = s1.createQuery("from com.test.hb.Hbtest h where h.id=?").setInteger(0, 1);
q1.setCacheable(true);

Query q2 = s1.createQuery("from com.test.hb.Hbtest h where h.id=?").setInteger(0, 1);
q2.setCacheable(true);

两个query是一样的,第二个query会用query的cache,不会从新查询数据库.

4,

Query q1 = s1.createQuery("from com.test.hb.Hbtest h where h.id=?").setInteger(0, 1);
q1.setCacheable(true);

Query q2 = s1.createQuery("from com.test.hb.Hbtest h where h.id=?").setInteger(0, 2);
q2.setCacheable(true);

从逻辑上将,两个query是不一样的,第二个query不会用query的cache,而是会从新查询数据库.

query的cache打开后用iterator的场景:

query的cache不会缓存第一次针对ID的SQL,后面iterator的时候,会根据session中的cache决定数据库的访问.可以说query的cache对

iterator方式没有影响.

**如果cache的是native SQL,两个query的sql 语句必须是一样的(包括大小写).如下面的例子会访问两次数据库.

Query q1 = s1.createSQLQuery("select val from Hbtest H where H.id=1");

Query q2 = s1.createSQLQuery("select val from Hbtest h where h.id=1");

而对于HQL则不会,HQL会被hibernate翻译成SQL,在这过程会'识别'出是不是相同的SQL.下面的例子只访问1次数据库.

Query q1 = s1.createQuery("from com.test.hb.Hbtest h1 where h1.id=1");

Query q2 = s1.createQuery("from com.test.hb.Hbtest h where h.id=1");

linux

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn