2009-08-27 71 views
17

当使用各种JDBC模板方法之一时,我对如何遍历/滚动大型结果集(不适合内存)感到困惑。即使没有Iterable接口的直接暴露,我也会至少期望RowCallbackHandler的实例被调用,而查询在完成后(或堆溢出)不会执行。Spring JDBC支持和大型数据集

我确实在this看看一个(这对我来说什么都没有改变,尽管是在精神this post在堆栈溢出类似),并在this后在春季论坛。后者似乎表明,在光标获取数据时,回调处理程序确实应该被调用。然而我的测试显示没有这样的行为。

的数据库是Oracle10g中。我正在使用11.1.0.7.0-Production驱动程序和Spring 2.5.6.SEC01。任何人想法如何迭代结果集,最好同时保持RowMapper的映射逻辑等?

回答

19

Oracle JDBC驱动程序对java.sql.Statement上的setFetchSize()方法提供了适当的支持,允许您控制驱动程序一次可以提取多少行。

但是,Spring使用的RowMapper通过将每行读入内存,获取RowMapper将其转换为对象并将每行对象存储在一个大列表中。如果结果集很大,那么不管JDBC如何获取行数据,这个列表都会变大。

如果您需要处理大型结果集,则RowMapper不可缩放。您可以考虑使用RowCallbackHandler,以及JdbcTemplate上的相应方法。 RowCallbackHandler并不指示如何存储结果,而是由您来存储它们。

+1

setFetchSize并没有改变我的东西,我尝试过使用它。您是否针对Oracle实例开发?对我来说RowCallBackHandler只是挂起,等待查询完成,因为我在我的OP中写道。 – yawn

+2

显然我在测试中的JDBC模板上忘记了afterPropertiesSet()之后的调用。尴尬,但现在它的工作原理:*) – yawn

4

这是驱动程序/连接是否将数据流式传输回给您或者是否将其发送回一个块的属性。例如,在SQL Server中,您使用的连接URL的SelectMethod属性:

jdbc:microsoft:sqlserver://gsasql03:1433;DatabaseName=my_db;SelectMethod=direct

direct值意味着其结果应该进来一气呵成。另一个选择是cursor,它允许您指定要连接到流结果反馈给你。我不确定什么样的数据源是Oracle数据源,恐怕

RowCallbackHandler肯定适合我。

+0

是的,最好你不要放到一个数据集,你会抓住记录,同时坚持让连接打开,询问是否有更多的记录。我在.NET中做到了这一点,并在性能方面有了很大的提升。我想象一下类似的java会存在,特别是在春天。 – Zoidberg

+0

@ * Zoidberg * - OP似乎在做正确的事情,使用行回调处理程序 –

+0

这听起来很有希望。不幸的是,我在Oracle JDBC文档中找不到与此SQL Server URL设置类似的任何内容。 – yawn

-2

这里是将java sql结果集全部拉入内存的一个好库。通过数据集

http://casperdatasets.googlecode.com

您可以滚动/迭代,你可以发出对其进行查询,并建立索引优化。它还实现了java.sql.resultset接口,以便您可以继续使用此数据集的结果对JDBC数据库进行最小化操作。

+0

它也有一个适配器将jdbc结果集转换为内存结果集 - 我假设你可以在你的spring jdbc结果回调方法中调用这个适配器。 –

+1

对不起,但“如何迭代/滚动大型结果集(*不适合内存*)”。 – yawn

5

您可以使用springjdbc-iterable库:

CloseableIterator<MyObj> iter = jt.queryForIter("select ...", params, mapper); 

迭代器将自动关闭,在耗尽或者可以手动关闭。它只能在事务范围内工作。

免责声明:我写这个库

0
  1. 创建扩展StoredProcedure
  2. 创建RowCallBackHandler,可以同时处理每一行,一个自定义的存储过程。
  3. 声明你的参数。如果您有结果集,请首先声明该结果集。使用SqlReturnResultSet类和使用您的RowCallBackHandler
  4. 声明任何其他参数创建
  5. 编译
  6. 我做的步骤2至5在我的客户的存储过程
  7. 的构造函数创建一个地图包含你输入参数
  8. 使用输入参数执行存储过程

我会提供代码,但下面的文章包含所有这些信息。

Calling Stored Procedures with Spring JDBC Templates