春季JDBC支持和大型数据集

2022-09-02 10:04:52

当使用各种JDBC模板方法之一时,我对如何迭代/滚动大型结果集(不适合内存)感到困惑。即使没有直接公开可迭代接口,我至少也希望RowCallbackHandler的实例在查询执行而不是在查询完成后(或堆溢出)被调用。

我确实看了一下这个(尽管在精神上与这个关于堆栈溢出的帖子相似,但它对我来说没有任何变化)和春季论坛中的这篇文章。后者似乎表明,当游标获取数据时,确实应该调用回调处理程序。然而,我的测试没有显示这种行为。

该数据库是一个Oracle10g。我使用的是 11.1.0.7.0-生产驱动程序和 Spring 2.5.6.SEC01。任何人如何迭代结果集,最好是在保留RowMapper等的映射逻辑的同时,有什么想法吗?


答案 1

Oracle JDBC 驱动程序对 on 上的方法有适当的支持,它允许您控制驱动程序一次性读取多少行。setFetchSize()java.sql.Statement

但是,正如Spring所使用的那样,通过将每行读取到内存中,获取将其转换为对象,并将每行的对象存储在一个大列表中。如果您的结果集很大,那么无论 JDBC 如何获取行数据,此列表都会变大。RowMapperRowMapper

如果需要处理较大的结果集,则 RowMapper 不可缩放。您可以考虑改用 JdbcTemplate 上的相应方法。 不规定结果的存储方式,而是由您来存储它们。RowCallbackHandlerRowCallbackHandler


答案 2

您可以使用 springjdbc-iterable 库:

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

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

免责声明:我写了这个库


推荐