使用可滚动结果集在休眠中批量读取数据

Posted

技术标签:

【中文标题】使用可滚动结果集在休眠中批量读取数据【英文标题】:Bulk reading of data in hibernate using scrollable result set 【发布时间】:2015-02-06 11:51:56 【问题描述】:

我正在阅读有关使用休眠 http://java.dzone.com/articles/bulk-fetching-hibernate 进行批量获取的博客。 在此,ScrollableResults 用作解决方案。这里我们仍然需要从会话中驱逐对象。 我不明白使用ScrollableResults(或scroll())与使用list() 有何不同。

换句话说,以下陈述在性能方面有何不同

 List<Employee> empList = session.createCriteria(Employee.class).list();
 ScrollableResults sc = session.createCriteria(Employee.class).scroll();

请告诉我。

【问题讨论】:

ScrollableResults 的工作方式类似于 Jdbc 的 ScrollableResultSet。它一个一个地获取数据。 【参考方案1】:

上面的代码似乎缺少一些设置。

Query query = session.createQuery(query);
query.setReadOnly(true);
// MIN_VALUE gives hint to JDBC driver to stream results
query.setFetchSize(Integer.MIN_VALUE);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
// iterate over results
while (results.next()) 
    Object row = results.get();
    // process row then release reference
    // you may need to flush() as well

results.close();

关注this链接了解更多详情和解释。

【讨论】:

【参考方案2】:

我参考了 Hibernate API 文档来了解 list() 和 scroll() 之间的区别。 ScrollableResults 就像一个游标。 ScrollableResults 的一个重要特性是它允许访问当前结果行中的第 i 个对象,而无需通过 get(int i) 函数初始化该行中的任何其他结果。 它还允许使用 next() 和 previous() 函数来回移动结果集。

例子:

  ScrollableResults sc = session.createQuery("select e.employeeName,e.employeeDept FROM Employee e").scroll(ScrollMode.SCROLL_INSENSITIVE);
      while(sc.next()) 
         String empName = (String)sc.get(0);
         System.out.println(empName);
         String empdept = (String)sc.get(1);
         System.out.println(empdept);
      

上述程序的输出将是employeeName 和employeeDept 的值。

现在假设您想要获取结果集的最后一条记录。使用 list() 您需要迭代整个结果。通过 ScrollableResults,您可以使用last() 函数。

注意ScrollableResults sc = session.createCriteria(Employee.class).scroll();应该被迭代为

 while(sc.next()) 
     Employee emp = (Employee)sc.get(0);
     System.out.println(emp.getname);
 

【讨论】:

感谢 Gaurav..有一件事..在执行这两个语句时,我可以看到 sql 语句被触发..这并不意味着两者都会将表中的所有行加载到内存中

以上是关于使用可滚动结果集在休眠中批量读取数据的主要内容,如果未能解决你的问题,请参考以下文章

多线程jpa读取时休眠空指针异常

JDBC API 可滚动可编辑的结果集

JDBC高级特性结果集,批量更新

如何使用休眠读取地理值?

Java实现从Redis中批量读取数据

如何批量读取bmp图片的原始高和宽