当我需要使用 JDBC 驱动程序从 PostgreSQL 数据库中读取数百万行数据库时,我总是使用游标,否则我会得到 OutOfMemoryError。这是我使用的模式(伪代码):
begin transaction
execute("declare cursor...")
while (true) {
boolean processedSomeRows = false
resultSet = executeQuery("fetch forward...")
while (resultSet.next()) {
processedSomeRows = true
...
}
if (!processedSomeRows) break
}
close cursor
commit
这是我想出在 Scala 中实现的更“功能性”的等价物:
begin transaction
execute("declare cursor...")
@tailrec
def loop(resultSet: ResultSet,
processed: Boolean): Boolean = {
if (!resultSet.next()) processed
else {
// Process current result set row
loop(resultSet, true)
}
}
while (loop(executeQuery("fetch forward..."), false))
; //Empty loop
close cursor
commit
我知道这是人为的,但是有没有更好的方法而不诉诸可变性?如果我尝试在 Haskell 中执行此操作,我可能会想出一个涉及 monad 的解决方案,但我不想让我的思绪落入那些“曲折的小段落,都一样”,因为它可能永远不会回来......