clojure.java.jdbc懒惰查询

时间:2016-09-29 09:03:59

标签: 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

3 个答案:

答案 0 :(得分:7)

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

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

特别是,请参阅其他选项?部分,了解您可能需要的特定于数据库的调整。您可以在任何可以打开新连接的函数上指定:auto-commit? false,并且可以在任何与查询相关的函数上指定:fetch-size和各种游标控件。请参阅此StackOverflow问题&回答PostgreSQL可能需要的细节:

Java JDBC ignores setFetchSize?

目前,您需要深入了解clojure.java.jdbc来源or the prepare-statement reference documentation,了解更多这些选项。我将继续研究社区文档,以显示所有这些信息。

答案 1 :(得分:6)

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

像这样解决了。

<ul class="subnav-links">
  <li class="new-in ">
    <a href="/de/t/new">New In</a>
  </li>
  <li class="sale ">
    <a href="/de/t/sale">Sale</a>
  </li>
  <li class="looks ">
    <a href="/de/pages/best_looks">Looks</a>
  </li>
  ...more lis omitted
</ul>

其中ul.subnav-links { -moz-column-count: 8; -webkit-column-count: 8; column-count: 8; -moz-column-gap: 0; -webkit-column-gap: 0; column-gap: 0; list-style-type: none; } li { display: inline-block; max-width: 90%; width: 80px; word-break: keep-all; } form { float: right; } 是一个使用惰性结果集的函数。

(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-transactionautoCommit未传递false,因此您必须自己制作:fetch-size

答案 2 :(得分:0)

您不需要上面的交易和预备语句。使用:result-set-fn导致延迟序列被消耗。您可能打算使用:row-fn代替。

有关详细信息please see The Clojure Cookbook.我也建议使用打印版本。

  

jdbc / query函数有几个可选的关键字参数   控制它如何构造返回的结果集。 :result-set-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"}]
  

:row-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"})