返回的resultset-seq
那个with-query-results
可能已经像你要得到的那样懒惰了。正如你所说,只要把手打开,懒惰只会起作用。没有办法解决这个问题。如果数据库句柄已关闭,则无法从数据库中读取。
如果您需要在句柄关闭后进行 I/O 并保留数据,则打开句柄,快速 slurp(打败懒惰),关闭句柄,然后处理结果。如果您想遍历某些数据而不一次将其全部保存在内存中,请打开句柄,获取数据的惰性序列,doseq
覆盖它,然后关闭句柄。
所以如果你想对每一行做一些事情(为了副作用)并丢弃结果而不将整个结果集吃到内存中,那么你可以这样做:
(defn do-something-with-all-foo [f]
(let [sql "select * from foo"]
(with-connection *db*
(with-query-results res [sql]
(doseq [row res]
(f row))))))
user> (do-something-with-all-foo println)
{:id 1}
{:id 2}
{:id 3}
nil
;; transforming the data as you go
user> (do-something-with-all-foo #(println (assoc % :bar :baz)))
{:id 1, :bar :baz}
{:id 2, :bar :baz}
{:id 3, :bar :baz}
如果您希望您的数据长期存在,那么您也可以使用read-all-foo
上面的函数将其全部吞下(从而克服懒惰)。如果您想转换数据,那么map
在您获取所有数据后对结果进行转换。那时您的数据都将在内存中,但map
调用本身和您的获取后数据转换将是惰性的。