在 Postgresql 中逐行处理 Java 8 JPA 存储库流

Posted

技术标签:

【中文标题】在 Postgresql 中逐行处理 Java 8 JPA 存储库流【英文标题】:Java 8 JPA Repository Stream row-by-row in Postgresql 【发布时间】:2017-09-01 13:13:14 【问题描述】:

阅读this 关于 mysql 定义了某些必需的查询提示(@QueryHints 注释),以便让 MySQL 逐行处理结果集。有谁知道 PostgreSQL 需要什么(如果有的话)?

这是 MySQL 存储库中的参考查询定义:

@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE))
@Query(value = "select t from Todo t")
Stream<Todo> streamAll();

【问题讨论】:

PostgreSQL 需要类似的设置(即ResultSet.TYPE_FORWARD_ONLY & 一个特定的 fetch-size)。但是,您可以随意控制 fetch-size (f.ex. the JDBC docs contains an example with st.setFetchSize(50))。还有另一个限制:在这种“可滚动”模式下只能运行一个查询。 我确实在 50 的文档中看到了该示例。上面的代码使用 Integer.MIN_VALUE,不知道 postgresql 会用它做什么,因此我的问题。另外,你能解释一下限制吗?所有连接都是这样吗?我假设其他查询可以并行运行? 不,PostgreSQL 的 JDBC 驱动程序允许在单个语句中进行多个查询。 (例如"INSERT INTO ...; SELECT ...;"):这在可滚动模式下是不允许的(而且通常无论如何都不能移植)。 -- 不要在 PostgreSQL 中对 fetch-size 使用负值。使用 @QueryHint(name=HINT_FETCH_SIZE,value="1") 进行逐行读取,使用 >1 进行批量读取(带有一些缓存),使用 "0" 关闭可滚动性。 对比setFetchSize(rows)应该在条件rows &gt;= 0不满足时抛出SQLException(MySQL的JDBC驱动程序不支持)。 这取决于您期望的行数以及行的宽度。所以我建议你测试多个变体。但我预测 fetch-size=1 不会是最快的,超过某个值,它会变得越来越慢(如果你达到你的 rowcount f.ex. 的数量,那么它实际上不会滚动任何东西) 【参考方案1】:

它的 PostgreSQL 等价物是:

@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "1")

对于对比setFetchSize(rows) 应该在条件rows &gt;= 0 不满足时抛出SQLException。 MySQL 的 JDBC 驱动程序不支持这一点。

尽管在 PostgreSQL 中,您实际上可以设置大于 1 的值,以允许 PostgreSQL 的 JDBC 驱动程序进行一些缓存。 50 的 docs' example 似乎是合理的(除非你有不合理的宽行)。您还可以选择此值作为预期行数的一部分。在部署您的应用程序之前测试一些变体。

【讨论】:

以上是关于在 Postgresql 中逐行处理 Java 8 JPA 存储库流的主要内容,如果未能解决你的问题,请参考以下文章

在批处理文件中逐行读取txt

在 C# 中逐行读取文件

如何在 Java 中逐行读取文本文件并分隔每一行的内容?

在python中逐行读取大文件

如何在 Julia 中逐行读取文件?

在 data.table 中逐行应用返回列表/矩阵的函数