我无法理解pool-db
和connection
函数的使用
在此connection pooling guide中。
(defn- get-pool
"Creates Database connection pool to be used in queries"
[{:keys [host-port db-name username password]}]
(let [pool (doto (ComboPooledDataSource.)
(.setDriverClass "com.mysql.cj.jdbc.Driver")
(.setJdbcUrl (str "jdbc:mysql://"
host-port
"/" db-name))
(.setUser username)
(.setPassword password)
;; expire excess connections after 30 minutes of inactivity:
(.setMaxIdleTimeExcessConnections (* 30 60))
;; expire connections after 3 hours of inactivity:
(.setMaxIdleTime (* 3 60 60)))]
{:datasource pool}))
(def pool-db (delay (get-pool db-spec)))
(defn connection [] @pool-db)
; usage in code
(jdbc/query (connection) ["Select SUM(1, 2, 3)"])
我们为什么不能简单地做?
(def connection (get-pool db-spec))
; usage in code
(jdbc/query connection ["SELECT SUM(1, 2, 3)"])
答案 0 :(得分:4)
延迟确保您在首次尝试使用连接池时创建连接池,而不是在加载名称空间时创建连接池。
这是一个好主意,因为您的连接池可能由于多种原因而无法创建,并且如果在命名空间加载期间失败,您将得到一些奇怪的行为-创建失败的连接池后的任何定义都不会例如被评估。
通常,应构造顶级var定义,以使它们在运行时不会失败。
请记住,它们也可能在AOT编译过程中进行评估,如下文合金所示。
答案 1 :(得分:0)
在您的应用程序中,您只想创建一个池并重用它。因此,delay用于包装(get-pool db-spec)方法,以便仅在第一次使用deref / @强制使用该方法时才调用该方法,并将其缓存在随后的池中返回强制通话
答案 2 :(得分:0)
区别在于,在延迟版本中,仅当调用池时才会创建池(如果所有内容都已缓存,则可能不会创建),但是非延迟版本无论如何都将实例化池,即始终,即使不使用数据库连接。
delay
仅在调用deref
时运行,否则不执行任何操作。
答案 3 :(得分:0)
我建议您使用现有的库来处理连接池,例如hikari-cp,它是高度可配置的,并且可以在许多SQL实现中使用。