clojure.java.jdbc懒惰查询

Mic*_*ent 5 postgresql jdbc clojure

我的查询基本上是一个select *.在开发中,这个表只有30000行,但在生产中它会更大.所以我想懒洋洋地使用这个查询.为什么下面的查询不是懒惰的?我正在使用Postgres 9.5.4.1.

(do
  (def pg-uri {:connection-uri "jdbc:postgresql://localhost/..."})
  (def row (atom 0))
  (take 10 (clojure.java.jdbc/query 
          pg-uri
          ["select * from mytable"]
          {:fetch-size 10
           :auto-commit false
           :row-fn (fn [r] (swap! row inc))}))
  @row) ;;=> 300000
Run Code Online (Sandbox Code Playgroud)

Sea*_*eld 8

clojure.java.jdbc这些天本机支持对大型结果集进行延迟处理(其他答案早于本机支持).请在此处查看有关它的社区文档:

http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html#processing-a-result-set-lazily

特别是,请参阅附加选项?您可能需要的特定于数据库的调整部分.您可以:auto-commit? false在任何可以打开新连接的函数上指定,并且可以:fetch-size在任何与查询相关的函数上指定和使用各种游标控件.有关PostgreSQL可能需要的详细信息,请参阅StackOverflow问题和答案:

Java JDBC忽略setFetchSize?

目前,您需要深入了解clojure.java.jdbc源代码prepare-statement参考文档以获取更多这些选项.我将继续研究社区文档,以显示所有这些信息.


Mic*_*ent 7

首先,请参阅https://jdbc.postgresql.org/documentation/83/query.html#query-with-cursor.

解决了这个问题.

(jdbc/with-db-transaction [tx connection]
  (jdbc/query tx
    [(jdbc/prepare-statement (:connection tx)
                              "select * from mytable"
                              {:fetch-size 10})]
     {:result-set-fn (fn [result-set] ...)}))
Run Code Online (Sandbox Code Playgroud)

where :result-set-fn是一个消耗惰性结果集的函数.

with-db-transaction照顾到autoCommit设置false. :fetch-size没有通过,query所以你必须prepare-statement自己做.