来自 Spring JdbcTemplate 的可迭代结果

Iterable result from Spring JdbcTemplate

Spring JdbcTemplate方便returns查询结果为单值、单行、集合。我的应用程序连续处理结果并且只处理一次,所以我不想用不必要的积累加载内存。需要 Iterator 之类的东西。试过这个:

    try (ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("jdbc-context.xml")) {
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jоdbcTemplate = new JdbcTemplate(dataSource);

        SqlRowSet rs = jоdbcTemplate.queryForRowSet("select rownum from dual connect by rownum <= ?", 15);

        while(rs.next()) {
            System.out.println(rs.getInt(1));
        }
    }

但好像SqlRowSet是Java标准ResultSet的断开版本,在实现中还是先累加查询结果。

如何从JdbcTemplate中获取可迭代的单遍查询结果而不进行累加?

解决方案

正如@GPI 所建议的那样

    try (ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("jdbc-context.xml")) {
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jоdbcTemplate = new JdbcTemplate(dataSource);

        ResultSetExtractor<Boolean> rse = new ResultSetExtractor<Boolean>() {

            @Override
            public Boolean extractData(ResultSet rs) throws SQLException, DataAccessException {

                while(rs.next()) {
                    System.out.println(rs.getInt(1));
                }
                return null;
            }
        };

        jоdbcTemplate.query("select rownum from dual connect by rownum <= ?", new Integer[] {15}, rse);
    }

至少它有效。似乎没有更自然的解决方案。可能会回到标准 JDBC 和 ResultSet.

如果您不想在代码的 "Spring side" 上积累任何东西,那么最简单的选择是调用 query using a ResultSetExtractor

ResultSetExtractor 由 JDBC ResultSet 提供,您可以从中进行迭代。

据我所知,没有办法拥有一个可迭代对象而不以某种方式缓存 SQL 内容(可迭代对象可以重新创建调用者想要的任意数量的迭代器,这意味着它必须能够 "remember" 一切。

也就是说,SQL 驱动程序本身可能会或可能不会缓存内容,这是另一个讨论,与 Spring 无关。

您应该阅读 SQL 驱动程序的文档以寻找可能的优化(获取大小、仅向前滚动性等),如果需要,请使用 Spring PreparedStatementCreator 来更改 Spring 用于构建查询的 JDBC 选项。