只是想了解clojureql开放全局性和有结果的目的。我从阅读此概述开始:How does ClojureQL compare to clojure.contrib.sql?
我以为出于某种原因,open-global将替换sql/with-connection,例如我认为这可以工作:
(def db {...}) ; connection details omitted
(open-global db)
(println (:name (first @(table :users)))
但是,这不起作用。似乎我既需要进行全局全局打开,又将执行的查询包装在(sql/with-connection db)中,这让我感到惊讶(我认为open-global提供了默认的全局可访问连接)。因此,既然情况似乎并非如此,我现在想知道它到底在做什么。
另外... with-results与仅使用@执行查询有何不同?因为似乎@(table:users)会给我一个执行查询的结果序列(不是with-results也一样)?
最佳答案
使用deref
(即@
符号)与with-results之间的区别非常微妙。基本上两者都做相同的事情,唯一的区别是查询实际执行的时间。两者实际上都只是apply-on
协议(protocol)的Relation
方法的包装器,这是with-results
的代码:
(defmacro with-results
[[results tble] & body]
`(apply-on ~tble (fn [~results] ~@body)))
对于
deref
:(deref [this]
(apply-on this doall))
如您所见,
deref
与以下内容完全相同:(with-results [res (table :users)] (doall res))
如果您查看
doall
文档,您会发现它是用于遍历惰性序列以强制产生任何副作用的函数,其结果是该序列将得到充分评估,因此不再是惰性的,而是驻留在该序列中。内存。因此,为了给您一个更深入的解释,使用
deref
会在调用时立即执行查询,而使用with-results
则会延迟执行查询,即实际使用结果时。至于
open-global
,您是对的,它确实应该打开一个全局可用的连接,如果不使用wiht-connection
指定一个连接,它将由ClojureQL使用。您观察到的行为可能是一个错误,因此建议您在IRC channel 或Github上的ClojureQL问题跟踪器中报告该行为。我已经有一段时间没有使用ClojureQL了,但是看一下代码,他们似乎已经过渡到使用clojure.java.jdbc
而不是clojure.contrib.sql
,那里可能出了点问题。关于clojureql,开放全局,有结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7178295/