来自 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 选项。
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 选项。