`

find和iterate区别

 
阅读更多

hibernate2中Session.find()对应于3中的session.createQuery().list();
hibernate2中Session.iterate()对应于3中的session.createQuery().iterate();


find和iterate区别:


find方法通过一条Select SQL实现了查询操作,而iterate方法要执行多条Select SQL.


iterate第一次查询获取所有符合条件的记录的id,然后再根据各个id从库表中读取对应的记录,这是一个典型的N+1次的查询问题,如果符合条件记录有10000条,就需要执行10001条Select SQL,可想性能会如何的差。

那为什么要提供iterate方法,而不只是提供高效率的find方法?

原因1.与hibernate缓存机制密切相关
find方法实际上是无法利用缓存的,它对缓存只写不读。
find方法只执行一次SQL查询,它无法判断缓存中什么样的数据是符合条件的,也无法保证查询结果的完整性。

iterate方法,会首先查询所有符合条件记录的id(此时发出一条sql语句),遍历时然后根据id去缓存中找,如果缓存中有该id,就返回(缓存中有不发sql语句),没有可以根据id再去数据库查询(没有发sql语句去数据库查询寻)。iterate方法可能会出现N+1问题。

String hql = "from TUser where age > ?";
List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);

 //顺序执行,iterate方法只会执行一次SQL查询,就是查找id,然后根据id就可以从缓存中获得数据

 

String hql = "from TUser where age > ?";
List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
userList = session.find(hql, new Integer(18), Hibernate.INTEGER); 

 //缓存是不起作用的


如果目标数据读取相对较为频繁,通过iterate这种机制,会减少性能损耗。

原因2.内存使用上的考虑
find方法将一次获得的所有记录并将其读入内存。如果数据量太大,可能会触发OutOfMemoryError,从而导致系统异常。

 

解决方案之一就是结合iterate方法和evict方法逐条对记录进行处理,将内存消化保持在一个可以接受的范围之内。如:

String hql = "from TUser where age > ?";
Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);
while(it.hasNext()) {
 TUser user = (TUser)it.next();

 //将对象从一级缓存中删除
session.evict(user);

 
   

//二级缓存可以设定最大缓存量,达到后自动对较老数据进行废除,但也可以通过编码移除,这样有助于保持数据有效性。
sessionFactory.evict(TUser.class, user.getID());

 

 

分享到:
评论

相关推荐

    getHibernateTemplate()有模糊查询和 分页

    `getHibernateTemplate().iterate(queryString).next()`这部分代码似乎是为了获取HQL查询("select count() from Info")的结果,即计算`Info`表中的记录总数。然而,这段代码可能不完整,因为它缺少关闭迭代器和...

    hibernateTemplate的常用方法

    - `find`和`iterate`的区别在于,如果查询结果较大时,`find`会一次性加载所有数据到内存中,可能导致性能问题;而`iterate`则是按需加载,更适合处理大量数据的情况。 3. **save/update/saveOrUpdate/delete**:...

    Hibernate方法总结

    `find` 和 `iterate`: 这两个方法都用于执行HQL(Hibernate Query Language)查询。`find`返回一个List集合,一次性将所有结果加载到内存,适合于小规模数据的查询。而`iterate`返回一个迭代器,每次调用`next()`...

    Hibernate对象持久化状态

    缓存会在特定时刻进行清理,如 `commit()`、`find()` 或 `iterate()` 调用后,`flush()` 方法执行时,或者使用 `setFlushMode()` 设置不同的清理策略。 2. Hibernate 中 Java 对象的状态 - **临时状态**:新创建但...

    Field Guide to Human-Centered Design

    - **Top Five Find Themes**: 提炼主题,识别主要的设计方向和主题。 - **Create Insight Statements**: 创造洞察陈述,形成基于研究的见解。 - **Explore Your Hunch**: 探索直觉,运用直觉和初步的想法来探索...

    Java stream的延迟计算.pdf

    Java Stream 是Java 8引入的一个强大特性,它允许程序员以声明式的方式处理数据集合,尤其在进行数据过滤、映射和归约等操作时。Stream API 提供了一种高效的、适用于大量数据处理的抽象概念,同时也支持延迟计算,...

    newtonmethod:牛顿法,求根

    牛顿法 // find an approximate solution to `x^2=612`var ( ƒ = func ( x float64 ) float64 { return x * x } dƒ = func ( x float64 ) float64 { return 2 * x } value = 612.0)// iterate 5 times, start with...

    backbone-http:BackboneORM 的 HTTP 接口

    这允许使用 BackboneORM 的统一查询语法和迭代方法从浏览器迭代远程集合。 示例(CoffeeScript) class Project extends Backbone.Model urlRoot : ' /projects ' sync : require ( ' backbone-http ' ). sync ...

    C++程序设计教学课件:CHAPTER 11 THE STANDARD TEMPLATE LIBRARY.ppt

    3. **算法**:STL提供了一组广泛的算法,这些算法不依赖于特定的容器实现,可以对容器中的元素进行操作,如排序(sort)、查找(find)、拷贝(copy)、删除(remove)等。这些算法大大简化了复杂操作的编写,提高了...

    MongoDB查询的JavaScript实现Mingo.zip

    搜索和过滤// filter collection with find() var cursor = query.find(collection); // shorthand with query criteria // cursor = Mingo.find(collection, criteria); // sort, skip and ...

    Struts2的标签库及OGNL表达式语言

    - 非UI标签主要包括条件判断(if、else)、循环(iterate)等,它们简化了JSP中的逻辑处理,提高了代码可读性和维护性。 Struts2的标签库极大地提升了开发效率,配合OGNL表达式语言,使得视图层的构建变得更加简洁...

    C++ 集合 set 例子

    标签:"C++ 集合 set 例子 iterate" 知识点: C++中的`set`容器是STL(标准模板库)的一部分,它提供了存储唯一元素的功能,这些元素会根据它们的值自动排序。`set`是一个关联容器,与`map`类似,但`set`主要用于...

    select:JavaScript数据库库

    选择 select是一个数据库库。 支持的数据库: ... // Find some items and iterate select('users') .find({ name: 'Alex' }) .limit(3) .offset(8) .each(function(index) { console.log(this

    利用ffmpeg从USB摄像头获取视频并保存为H264的TS流的C语言源代码

    3. 遍历流:通过`avformat_iterate_streams()`遍历设备提供的所有流,查找视频流。视频流可以通过检查`AVStream->codecpar->codec_type`是否为`AVMEDIA_TYPE_VIDEO`来识别。 4. 找到合适的编码器:利用`avcodec_...

    DELPHI字符串链表类

    5. **遍历操作**:为了访问链表中的所有字符串,类可能包含一个`ForEach`或`Iterate`方法,它迭代每个节点并执行用户提供的回调函数。 6. **查找操作**:查找特定字符串的节点也是链表类的重要功能,可能有一个`...

    域模型的种状态与hibernate缓存PPT学习教案.pptx

    - `find()`或`iterate()`等查询操作时,确保返回最新数据。 - 显式调用`flush()`方法时。 【Hibernate的二级缓存】 除了Session的一级缓存,Hibernate还提供二级缓存,由SessionFactory管理,是跨Session的全局...

    struts常见错误以及解决

    - 确保`<logic:iterate>`标签中的`id`和`name`属性正确无误。 - 在迭代过程中,使用`id`属性定义的变量名来进行数据展示,而不是`name`属性中的bean名。 4. **Action映射配置错误:** 当JSP页面中的`...

    Hibernate缓存机制

    - `find`方法用于执行远端查询,即直接从数据库中获取数据。 - **1.2.2. N+1查询问题** - 当使用`iterate`遍历查询结果时,可能会引发N+1次查询的问题。 - “N+1”中的“1”是指第一次查询,而“N”则是指后续...

    Palindrome:查找数字中最近的较大回文

    我们可以通过递增的方式遍历,同时使用Java 8的Stream API和`findFirst()`方法来实现这一点: ```java public int nearestLargerPalindrome(int num) { IntStream stream = IntStream.iterate(num + 1, i -> i + 1...

    Java8 Stream学习

    - **使用Stream.iterate()**:可以创建基于初始值和迭代规则的无限流。 ```java Stream<Integer> iterateStream = Stream.iterate(42, n -> n + 2).limit(10); ``` - **基本类型的流**:对于int、long和double...

Global site tag (gtag.js) - Google Analytics