java-8 - 如何从 jdbc 结果集中返回 java8 Stream
问题描述
为了充分利用 java8 流和 Spring4,我在来自 Springs jsdbRestTemplate 的 JDBC resultSet 上使用 Stream API,如下所示(代码缩短和简化):
public <T> T consumeResultStream(
String query,
Function<Stream<String>, T> extractorFunction
) {
return jdbcTemplate.query(
query,
resultSet -> {
Spliterator<String> spliterator =
Spliterators.spliteratorUnknownSize(
new Iterator<String>() {
@Override public boolean hasNext() {
return !resultSet.isAfterLast();
}
@Override public String next() {
String result = resultSet.getString(0);
resultSet.next();
return result;
}
},
Spliterator.IMMUTABLE);
resultStream = StreamSupport.stream(
spliterator, /*parallel*/ false);
}
return extractorFunction.apply(resultStream);
});
}
这似乎工作正常。客户端可以像这样使用流Api而不用担心jdbc类
List<T> myResult = consumeResultStream("SELECT ...", stream ->
stream.filter((String s) -> ...)
.map(String s -> toT(s))
.collect(toList()));
但是,当我重构时(尝试将流提供给客户端方法),如下所示:
final Stream<String> stream =
jdbcTemplate.query(query, resultSet -> {
// ... same as above
return resultStream;
});
return extractorFunction.apply(stream);
我明白了
org.springframework.jdbc.InvalidResultSetAccessException:
The object is already closed [90007-199]
所以看起来数据只能在jdbcTemplate.query()
方法内读取。有没有一种干净的方法可以规避这个问题并返回来自数据库的元素的惰性流?假设由于结果的大小而无法选择实现结果和流式传输(尽管分页可能是更好的模式)。
解决方案
JdbcTemplate
JPA
与 Spring特性相反,不处理超出其调用的事务。
要不允许关闭数据库连接,请从客户端打开一个操作返回的惰性结果的事务。
用注释@Transactional
通常就足够了:
@Transactional
public void findLazyData(){
Stream<String> result = dataAccessService.find(...);
// where find() contains the JdbcTemplate invocation
}
注意包的来源:org.springframework.transaction.annotation.Transactional
.
推荐阅读
- python - cron 作业中的 Python subprocess.popen
- amazon-web-services - 如何使用 vagrant 创建 ec2 实例?
- eclipse - 如何在 Eclipse 中同步拆分编辑器窗格?
- javascript - 如何根据键而不是值在 MongoDB 集合中删除文档?
- python - 从二进制文件中解析特定字符串
- reactjs - Context.Consumer 与 useContext() 访问 Context.Provider 传递的值
- rest - UE 4 - 如何通过 webapi 与 Steam 集成设置服务器配置文件
- python-2.7 - 为什么返回 None;dec2asc?
- ionic-framework - 使用cordova时,离子应用程序不会在服务器上运行
- python - 如何在开放端口上保护 python 套接字侦听、发送和接收?