Hibernate中用hql通过query进行查询的时候,通常会用list或者iterate取得查询到的结果.在此简单说明一下这两个方法的不同之处和适用场景.
List:查询到的结果会被完整地放进内存(session的缓存),实体会处于持久状态.如果用迫切连接(fetch)模式,取得的结果可能会存在主表对应的一条记录会在list里存在多个实例(准确的讲是实例引用),多次出现但是指向同一个对象.list只会执行一条SQL语句.
Iterate:会在第一次把所有的id查询出来,然后在真正iterate的时候,根据session的缓存中是否存在对应的对象而决定是否上数据库查询.如果session的缓存中不存在,通常会产生1+N次SQL查询.
list example:
s1 = sessionFactory.openSession();
Query q = s1.createQuery("from com.test.hb.Hbtest h where h.id<2");
List 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<2
iterate example:
s1 = sessionFactory.openSession();
Query q = s1.createQuery("from com.test.hb.Hbtest h where h.id<2");
Iterator itr = q.iterate();
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<2
两条根据id取记录的SQL(缓存中不存在于该id对应的记录)
select hbtest0_.ID as ID0_0_, hbtest0_.VAL as VAL0_0_ from HB.HBTEST hbtest0_ where hbtest0_.ID=?
使用场景:如果在cache中不存在对应的记录时,用list方法.如果大量的记录已经在cache中存在,用iterate性能更好.
query 的cache打开后对list和iterator方式的影响:
将query 的cache打开的话,缓存的是query本身,以hql 生成的 sql ,再加上参数,分页等信息做为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<3");
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");
相关推荐
今天我们将探讨的是Hibernate的二级缓存,特别是`list`和`iterate`方法的区别,这对于优化数据库访问性能至关重要。 一级缓存是Hibernate内置的,它是Session级别的缓存,自动管理实体对象的生命周期。然而,一级...
### HIBERNATE_QUERY知识点详解 #### 一、概述 Hibernate作为一款强大的对象关系映射...以上就是关于Hibernate查询机制的相关知识点介绍,通过这些方法和技术,开发者可以根据具体的应用需求选择最合适的查询方式。
文章作者通过实际代码示例展示了在Hibernate中如何使用`list()`和`iterator()`方法获取并遍历查询结果。源码是配合文章内容的实践案例,帮助读者更好地理解和应用这些概念。 【标签】"Hibernate" Hibernate是Java...
这两个方法都用于执行HQL(Hibernate Query Language)查询。`find`返回一个List集合,一次性将所有结果加载到内存,适合于小规模数据的查询。而`iterate`返回一个迭代器,每次调用`next()`方法时才从数据库中获取一...
//该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...
本文将详细介绍如何利用Struts和Hibernate来实现对Oracle数据库中所有记录的查询及显示功能。 #### 二、技术背景介绍 1. **Struts**:Struts是一个开源的MVC(Model-View-Controller)框架,主要用于简化Web应用...
List<Customer> customers = query.list(); ``` ##### 4. QBC方式(Query By Criteria) - **定义**:QBC是Hibernate提供的另一种查询方式,基于标准的Java API,提供了更多的灵活性。 - **应用场景**:构建复杂...
关于iterate和list的使用,由于无法确保查询条件的重复性,通常很难保证iterate能充分利用缓存。而且,iterate可能会导致1+N问题,因为即使有缓存,每次迭代时仍需检查数据库是否存在新数据。相比之下,list在某些...
Query 对象提供了许多方法来查询持久化对象,例如 list、iterate 等。Query 对象可以根据不同的条件来查询持久化对象。 Hibernate 的核心接口分别是 Configuration、SessionFactory、Session、Transaction 和 Query...
`单端代理的批量抓取.PNG` 可能讲解了如何通过Hibernate的批处理技术提高性能,如设置批处理大小,利用Session的flush模式,以及Query的iterate()和list()方法的区别。批量操作可以减少数据库交互次数,提升应用性能...
无论是通过list、load还是iterate操作,一旦从数据库中读取到对象,都会将其存入缓存。不过,值得注意的是,list操作不会直接使用缓存,而iterate操作会先从数据库获取ID,然后逐个load,如果对象在缓存中存在,就...
该方法的参数包括Query对象、参数名称和参数值。通过该方法,可以将命名参数绑定到查询对象中,以便在查询执行时可以正确地使用参数。 bulkUpdate方法 该方法用于执行批量更新或删除操作。该方法有三个重载版本,...
2. **查询**: Hibernate提供HQL(Hibernate Query Language)和Criteria API进行查询,HQL类似于SQL,Criteria API更加面向对象。 3. **检索**: `Session`的`get()`、`load()`方法获取单个实体,`list()`, `scroll()...
不同的操作,如`list`、`load`和`iterate`,对缓存的使用策略不同。`list`操作不会使用缓存,而`iterate`会先查询所有ID,然后逐个从缓存或数据库加载对象。 在Ehcache配置中,`maxElementsInMemory`定义了缓存中...
- 使用`Query.iterate()`、`load`、`get`等方法可以从缓存中加载数据。 - `find`方法用于执行远端查询,即直接从数据库中获取数据。 - **1.2.2. N+1查询问题** - 当使用`iterate`遍历查询结果时,可能会引发N+1...
但是需要注意的是,`list`操作本身不会使用缓存,而`iterate`则会先尝试从缓存中获取数据,若缓存中不存在,则再从数据库加载。 此外,还可以通过设置`cache-usage`属性来指定缓存的使用模式,如`read-only`、`read...
在Hibernate中,你可以通过`Session`对象的`createSQLQuery`方法创建一个SQL查询。例如: ```java Query query = session.createSQLQuery("select * from t_user usr"); ``` 执行上述代码后,Hibernate将会执行...