Spring JdbcTemplate的可迭代结果

时间:2019-01-23 11:54:29

标签: java spring iterator 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

1 个答案:

答案 0 :(得分:0)

如果您不想在代码的“弹簧侧”上积累任何内容,那么最简单的选择是使用query来调用ResultSetExtractor

ResultSetExtractor附带了您可以从中进行迭代的JDBC ResultSet

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

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

您应该阅读SQL Driver的文档以寻找对此的可能的优化(获取大小,仅向前滚动性……),并在需要时使用Spring PreparedStatementCreator来更改Spring使用的JDBC选项。建立查询。