clojure.java.jdbc懒查询clojure.java.jdbc懒查询(clojure.j

2019-05-12 05:53发布

我有一个查询,基本上是一个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

Answer 1:

clojure.java.jdbc支持大型结果迟缓处理本身设置这些天(这里的其他答案早是原生支持)。 在这里看到关于它的社区文档:

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

特别是,看到其他选项? 部分你可能需要特定于数据库的调整。 您可以指定:auto-commit? false :auto-commit? false的,将打开一个新的连接,您可以指定任何功能:fetch-size和任何查询相关功能的各个光标控制。 见什么PostgreSQL的可能需要细节这个StackOverflow的问题和答案:

Java的JDBC忽略的setFetchSize?

目前,你必须在挖clojure.java.jdbc源或prepare-statement参考文档获取更多的这些选项。 我继续对社区工作的文件表面所有信息。



Answer 2:

首先,看看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] ...)}))

其中:result-set-fn是消耗懒惰结果集的函数。

with-db-transaction需要照顾的autoCommit设置为false:fetch-size不从通过query ,所以你必须做出prepare-statement自己。



Answer 3:

你不需要交易,并准备语句的东西上面。 它是利用的:result-set-fn引起懒惰序列被消耗。 你可能想用的是:row-fn代替。

有关详情请参阅Clojure的食谱。 打印版本也已经推出,我建议。

的jdbc /查询功能具有控制它如何构建返回的结果集多种可选关键字参数。 的:结果集-FN参数指定被返回之前,被施加到整个结果集的函数(懒惰序列)。 默认参数是DOALL功能:

(defn hi-lo [rs] [(first rs) (last rs)])

;; Find the highest- and lowest-cost fruits
(jdbc/query db-spec
            ["select * from fruit order by cost desc"]
            :result-set-fn hi-lo)
;; -> [{:grade nil, :unit nil, :cost 77, :appearance nil, :name "Kumquat"}
;;     {:grade 1.4, :unit nil, :cost 10, :appearance "rotten", :name "Tomato"}]

的:行-FN参数指定作为结果构成的,即施加到每个结果行的函数。 默认参数是身份的功能:

(defn add-tax [row] (assoc row :tax (* 0.08 (row :cost))))

(jdbc/query db-spec
             ["select name,cost from fruit where cost = 12"]
             :row-fn add-tax)
;; -> ({:tax 0.96, :cost 12, :name "Plum"} {:tax 0.96, :cost 12, :name "Fig"})


文章来源: clojure.java.jdbc lazy query