只是想了解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/

10-11 16:28