我的查询基本上是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
答案 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-transaction
。
autoCommit
未传递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"})