在 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 >= 0
不满足时抛出SQLException
(MySQL的JDBC驱动程序不支持)。
这取决于您期望的行数以及行的宽度。所以我建议你测试多个变体。但我预测 fetch-size=1 不会是最快的,超过某个值,它会变得越来越慢(如果你达到你的 rowcount f.ex. 的数量,那么它实际上不会滚动任何东西)
【参考方案1】:
它的 PostgreSQL 等价物是:
@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "1")
对于对比setFetchSize(rows)
应该在条件rows >= 0
不满足时抛出SQLException
。 MySQL 的 JDBC 驱动程序不支持这一点。
尽管在 PostgreSQL 中,您实际上可以设置大于 1
的值,以允许 PostgreSQL 的 JDBC 驱动程序进行一些缓存。 50
的 docs' example 似乎是合理的(除非你有不合理的宽行)。您还可以选择此值作为预期行数的一部分。在部署您的应用程序之前测试一些变体。
【讨论】:
以上是关于在 Postgresql 中逐行处理 Java 8 JPA 存储库流的主要内容,如果未能解决你的问题,请参考以下文章