连接:发生了什么?

Woj*_*zki 9 jdbc clojure

在我的Clojure项目中,我将依赖项更改[org.clojure/java.jdbc "0.2.3"][org.clojure/java.jdbc "0.3.3"]

我收到以下错误:

clojure.lang.Compiler $ CompilerException:java.lang.RuntimeException:没有这样的var:sql/with-connection,编译:(/ Volumes/HD2/env/prj/restore/src/restore/db.clj:80:5)

发生了什么?这个功能是否已被弃用?

背景:我需要执行!0.2.3没有它.0.3.3有它,但缺乏连接?!?

请帮忙.

Nie*_*lsK 23

with-connection不仅因为leonardoborges提到的原因而被认为是有害的,它还使得连接池的使用更加困难.从特定连接中解耦函数数据库访问使得模型更容易.强制查询使用相同的连接应该是例外,而不是规则.所以clojure.core/java.jdbc 0.3.0专门用于弃用with-connection.为了适应这种情况,需要更改整个API.

现在,每个数据库访问函数都将db规范作为参数.如果db-spec是连接池,则该函数将在其中一个连接上执行,否则将从db-spec创建隐式新连接.因此,当不使用连接池时,所有数据库访问函数都会导致连接.

这也意味着不能再懒惰地返回结果集.以前,处理延迟序列可能会在仍然在with-connection块内时推迟.现在,它们需要在函数执行期间实现,或者可以关闭其连接,或者可以从池中返回新连接以用于下一个访问函数.

因此,现在可以通过两个新的命名参数在函数本身的范围内完成处理::row-fn:result-set-fn.第一行转换每行,第二行转换行.如果:result-set-fn返回延迟序列,则稍后使用时将获得连接或结果集关闭异常.默认:result-set-fndoall.使用自己的时,请确保它已实现.

对于一般情况来说,访问和连接是分离的.现在为例外:需要使用相同连接的函数.

其中最常见的是事务使用,它使用范围来指示事务的开始和结束.旧的transaction只提供了这个范围.新with-db-transaction函数绑定了一个新的var和dp-spec.

此var将绑定到池中的一个特定连接,或者在未使用连接池时绑定到新创建的连接.块内使用的所有数据库访问函数都应使用var而不是db-spec参数.

(def db {..})

(with-db-transaction
  [c db]
  (let [from 1111
        to 2222
        sum 10
        saldo-from (query c ["select saldo from account where id=?" from]
                          :row-fn :saldo
                          :result-set-fn first)
        saldo-to (query c ["select saldo from account where id=?" to]
                        :row-fn :saldo
                        :result-set-fn first)]
    (update! c :account {:saldo (- saldo-from sum)} ["id=?" from])
    (update! c :account {:saldo (+ saldo-to sum)} ["id=?" to])))
Run Code Online (Sandbox Code Playgroud)

一个begin transaction命令将开始发行.所有访问都将使用现在专门传递给函数的相同连接,而不是通过动态范围魔术.如果没有生成异常,commit将在范围的末尾给出a .

当一个特定的连接,但不需要事务机制时,有with-db-connection一个具有相同语义的函数.因此,如果要执行命令来设置会话设置,并对该连接执行某些查询,则可以执行以下操作:

(def db {..})

(with-db-connection [c db]
                    (execute! c ["alter session set NLS_SORT='ITALIAN'"])
                    (query c ["select * from person where name=?" "Mario"]
                           :row-fn (comp concat (juxt :name :surname))))
Run Code Online (Sandbox Code Playgroud)

连接池通常具有特异性on-open,并on-close认为是其功能的一部分的命令.使用该池中的所有连接将具有相同的会话设置集,with-db-connection甚至根本不需要.


leo*_*ges 5

正如@mac所提到的,with-connection已被弃用.原因是它对客户端代码施加了不必要的约束,特别是在多线程环境中.

我建议您阅读Stuart Sierra的这篇文章,他将讨论这个以及与动态范围相关的其他问题.


mac*_*mac 2

在 3.3 中可以找到 with-connection clojure.java.jdbc.deprecated