首页 > 解决方案 > Spring JdbcTemplate 的可迭代结果

问题描述

Spring JdbcTemplate方便地将查询结果返回为单值、单行和集合。我的应用程序连续处理结果并且只处理一次,所以我不想加载不必要的内存。需要类似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.

标签: javaspringiteratorjdbctemplate

解决方案


如果您不想在代码的“Spring 方面”累积任何内容,那么您最简单的选择是query使用ResultSetExtractor

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

据我所知,没有办法拥有一个 Iterable 并且不以某种方式缓存 SQL 内容(iterables 可以根据调用者的需要重新创建尽可能多的迭代器,这意味着它必须能够“记住”所有内容)。

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

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


推荐阅读