Jdbc 与连接:发生了什么?
在我的Clojure项目中,我将依赖项从Jdbc 与连接:发生了什么?,jdbc,clojure,Jdbc,Clojure,在我的Clojure项目中,我将依赖项从[org.Clojure/java.jdbc“0.2.3”]更改为[org.Clojure/java.jdbc“0.3.3”] 我收到以下错误: clojure.lang.Compiler$CompilerException:java.lang.RuntimeException:没有这样的变量:sql/带连接,编译:(/Volumes/HD2/env/prj/restore/src/restore/db.clj:80:5) 发生了什么事?此函数是否已弃用
[org.Clojure/java.jdbc“0.2.3”]
更改为[org.Clojure/java.jdbc“0.3.3”]
我收到以下错误:
clojure.lang.Compiler$CompilerException:java.lang.RuntimeException:没有这样的变量:sql/带连接,编译:(/Volumes/HD2/env/prj/restore/src/restore/db.clj:80:5)
发生了什么事?此函数是否已弃用
背景:我需要执行!0.2.3没有。0.3.3有,但没有连接
请提供帮助。在3.3中的
clojure.java.jdbc中找到了连接。不推荐使用正如@mac所提到的,带有连接的不推荐使用。原因是它对客户机代码施加了不必要的约束,特别是在多线程环境中
我建议您阅读Stuart Sierra的一篇文章,其中介绍了这个问题以及其他与动态范围相关的问题。与连接的关系
不仅因为leonardoborges提到的原因被认为是有害的,而且还使使用连接池变得更加困难。将函数数据库访问与特定连接分离可以使模型更加简单。强制查询使用相同的连接应该是例外,而不是规则。因此clojure.core/java.jdbc0.3.0是专门设计用来反对连接的。为了适应这种情况,整个API都需要更改
现在,每个数据库访问函数都将db spec作为参数。如果db-spec是一个连接池,那么函数将在它的一个连接上执行,否则将从db-spec建立一个隐式的新连接。因此,所有数据库访问函数都会在不使用ConnectionPool时产生一个连接
这也意味着结果集不能再延迟返回。以前,在with连接块中处理惰性序列可能会被延迟。现在,它们需要在函数执行期间实现,或者可以关闭其连接,或者可以从池中返回一个新连接以用于下一个访问函数
因此,现在可以通过两个新的命名参数在函数本身的范围内完成处理::row fn
和:result set fn
。第一个转换每行,第二个转换行集合。如果:result set fn
返回一个延迟序列,那么在以后使用它时,您将得到一个连接或resultset closed异常。默认的:结果集fn
是doall
。当使用你自己的时,确保它被实现
一般情况下,访问和连接是解耦的。现在是例外:需要函数使用相同的连接
其中最常见的是事务使用,它使用范围来指示事务的开始和结束。旧的事务
仅提供此范围。新的with db transaction
函数接受新var和dp-spec的绑定
此变量将绑定到池中的一个特定连接,或者在未使用连接池时,绑定到新创建的连接。块内使用的所有db访问函数都应使用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])))
开始时将发出begin transaction
命令。所有访问都将使用现在专门传递给函数的相同连接,而不是通过动态范围魔法。当没有生成异常时,将在作用域的末尾给出一个commit
当只需要一个特定的连接,但不需要事务机制时,就有具有相同语义的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))))
连接池通常在打开时有特定的命令,在关闭时有特定的命令,这是它们规范的一部分。使用这些连接时,来自该池的所有连接都将设置相同的会话设置,甚至根本不需要使用数据库连接的