我只是想理解clojureql的open-global和with-result的目的。我从阅读这个概述开始:How does ClojureQL compare to clojure.contrib.sql?
出于某种原因,我认为open-global会用-connection取代sql/,例如,我认为这会起作用:
(def db {...}) ; connection details omitted
(open-global db)
(println (:name (first @(table :users))) 然而,这并不起作用。似乎我既需要执行open-global,又需要将执行中的查询包装在一个(sql/with-connection db)中,这让我有点惊讶(我以为open-global提供了一个默认的全局可访问连接)。因此,由于情况似乎并非如此,我现在想知道它到底是做什么的。
Also...how使用-results不同于简单地使用@?因为@(table :users)似乎会给我留下一个序列,它是执行查询的结果(这不也是with-results做的事情吗)?
发布于 2011-08-25 23:45:43
使用deref ( @符号)和with-results之间的区别非常微妙。基本上两者都做同样的事情,唯一的区别是查询实际执行的时间。它们实际上都只是Relation协议的apply-on方法的包装器,下面是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使用。您正在观察的行为可能是一个bug,所以我建议您在IRC频道或Github上的ClojureQL问题跟踪器上报告它。我已经有一段时间没有使用ClojureQL了,但是看一下代码,他们似乎已经过渡到使用clojure.java.jdbc而不是clojure.contrib.sql了,可能出了什么问题。
https://stackoverflow.com/questions/7178295
复制相似问题