6

只是想了解 clojureql 的 open-global 和 with-results 的目的。我首先阅读了这篇概述:ClojureQL 与 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)中,这让我感到惊讶(我认为开放全局提供了默认的全局可访问连接)。因此,既然情况似乎并非如此,我现在就想知道它到底做了什么。

另外... with-results 与简单地使用@ 执行查询有何不同?因为似乎 @(table :users) 会给我留下一个执行查询结果的序列(这不是 with-results 的作用吗)?

4

1 回答 1

3

derefusing (the symbol) 与 with-results之间的区别@非常微妙。基本上两者都做同样的事情,唯一的区别是查询实际执行的时间。两者实际上只是协议apply-on方法的包装器,下面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,您是对的,它确实应该打开一个全局可用的连接,当没有指定一个 using 时,ClojureQL 将使用该连接wiht-connection。您观察到的行为可能是一个错误,因此我建议您在 IRC 频道或 Github 上的 ClojureQL 问题跟踪器上报告它。我有一段时间没有使用 ClojureQL,但是查看代码,它们似乎已经转换为 usingclojure.java.jdbc而不是clojure.contrib.sql,那里可能出现了问题。

于 2011-08-25T15:45:43.420 回答