When using one of the various JDBC template methods I am confused on how to iterate/scroll over large result sets (which won\'t fit into memory). Even without a direct expos
It's a property of the driver/connection whether to stream data back to you or whether to send it back in one chunk. For example, in SQL Server, you use the SelectMethod
property on the connection URL:
jdbc:microsoft:sqlserver://gsasql03:1433;DatabaseName=my_db;SelectMethod=direct
The value of direct
means that the results should come in one go. The other choice is cursor
, which allows you to specify that you want the connection to stream results back to you. I'm not sure what the analog for an Oracle data source is, I'm afraid
the RowCallbackHandler
certainly works for me.
The Oracle JDBC driver has proper support for the setFetchSize()
method on java.sql.Statement
, which allows you to control how many rows the driver will fetch in one go.
However, RowMapper
as used by Spring works by reading each row into memory, getting the RowMapper
to translate it into an object, and storing each row's object in one big list. If your result set is huge, then this list will get big, regardless of how JDBC fetches the row data.
If you need to handle large result sets, then RowMapper isn't scaleable. You might consider using RowCallbackHandler
instead, along with the corresponding methods on JdbcTemplate. RowCallbackHandler
doesn't dictate how the results are stored, leaving it up to you to store them.
StoredProcedure
RowCallBackHandler
that can handle each row, one at a time.SqlReturnResultSet
class and create it using your RowCallBackHandler
I would provide code, but the following article contains all of this information.
Calling Stored Procedures with Spring JDBC Templates
here's a good library for pulling java sql resultsets all into memory.
http://casperdatasets.googlecode.com
you can scroll / iterate through the dataset, you can issue queries against it, and build indexes for optimization. it also implements the java.sql.resultset interface so you can continue to operate on results from this dataset with minimals chnages to your jdbc code.
You may use springjdbc-iterable library:
CloseableIterator<MyObj> iter = jt.queryForIter("select ...", params, mapper);
Iterator will be auto-closed on exhaustion or may be closed manually. It will work only within transaction bounds.
Disclaimer: I wrote this library