gpt4 book ai didi

java-8 - 如何从jdbc结果集中返回java8 Stream

转载 作者:行者123 更新时间:2023-12-02 06:45:06 25 4
gpt4 key购买 nike

为了充分利用 java8 流和 Spring4,我在来自 Springs jsdbRestTemplate 的 JDBC 结果集上使用 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 不处理其调用之外的事务,这与 Spring JPA 功能相反。
为了不允许关闭数据库连接,请从客户端打开一个事务来操作返回的延迟结果。
@Transactional 注释它通常就足够了:

@Transactional
public void findLazyData(){
Stream<String> result = dataAccessService.find(...);
// where find() contains the JdbcTemplate invocation
}

注意包来源:org.springframework.transaction.annotation.Transactional

关于java-8 - 如何从jdbc结果集中返回java8 Stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56897528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com