Когда мне нужно прочитать миллионы строк базы данных из базы данных PostgreSQL с помощью драйвера JDBC, я всегда использую курсор, иначе я получу ошибку 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, я мог бы придумать решение, включающее монады, но я не хочу посылать свой разум по этим "извилистым маленьким проходам, похожим друг на друга", потому что он может никогда не вернуться...
Iterator
s, либоStream
s для обработкиResultSet
s, но я не могу придумать способ остановить итерацию (аргументprocessed
выше). - person Ralph   schedule 09.10.2012takeWhile
), чтобы посмотреть, смогу ли я завершить внешний циклwhile
. - person Ralph   schedule 09.10.2012