在Clojure中,存储全局连接的正确方法是什么?

7

我有以下文件,作为API端点连接到我的数据库。如何正确地维护单个连接(或连接池)的服务器寿命?

(ns my-api.repository
  (:require [clojure.java.jdbc :as sql]))

(defn some-query
  (sql/with-connection (System/getenv "DATABASE_URL")
    (sql/with-query-results results
      ;; You get the picture
      )))
4个回答

5

如果您使用单个连接的with-connection宏,那么会存储DATABASE_URL。您可以使用c3p0库进行连接池:

(defn pooled-spec
  "return pooled conn spec.
   Usage:
     (def pooled-db (pooled-spec db-spec))
     (with-connection pooled-db ...)"
  [{:keys [classname subprotocol subname user password] :as other-spec}]
  (let [cpds (doto (ComboPooledDataSource.)
               (.setDriverClass classname)
               (.setJdbcUrl (str "jdbc:" subprotocol ":" subname))
               (.setUser user)
               (.setPassword password))]
    {:datasource cpds}))

3
我还建议使用c3p0。 Clojure连接池提供了一个简洁的介绍,如何将clojure.java.jdbc与c3p0配置。

2

jdbc-pool 简化了使用 C3P0 和 clojure.java.jdbc 的过程。我专门为这个目的创建了该库。


0

我认为 with-connection 不会保持任何开放的内容。文档和源代码都没有这样的建议,在 2.3 版本中,我可以通过检查运行查询后的 db 来确认它。源代码如下:

(defn with-connection*
  "Evaluates func in the context of a new connection to a database then
  closes the connection."
  [db-spec func]
  (with-open [^java.sql.Connection con (get-connection db-spec)]
    (binding [*db* (assoc *db* :connection con :level 0 :rollback (atom false))]
      (func))))

连接池可能在懒惰地创建它们时很有用,但这并不能使它们保持打开状态。设置连接似乎是必要的。然而,最新的API强调只创建连接并将其传递到每个调用中。虽然仍处于ALPHA版本阶段,但这似乎是该库的未来趋势(并且仍与连接池兼容)。引自该库的维基:

(require '[clojure.java.jdbc :as j]
     '[clojure.java.jdbc.sql :as s])

(def mysql-db {:subprotocol "mysql"
               :subname "//127.0.0.1:3306/clojure_test"
               :user "clojure_test"
               :password "clojure_test"})

(j/insert! mysql-db :fruit
  {:name "Apple" :appearance "rosy" :cost 24}
  {:name "Orange" :appearance "round" :cost 49})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接