【发布时间】:2017-12-01 13:56:30
【问题描述】:
我有一个简单的 DAO ns:
(ns alavita.dao
(:require
[clojure.tools.logging :as log ]
[clojure.java.io :as io ]
)
(:import
[org.jdbi.v3.core Jdbi Handle]
))
(defn create
(^Jdbi [^String url]
(Jdbi/create url))
(^Jdbi [^String url ^String username ^String password]
(Jdbi/create url username password)))
(defn open
^Handle [^Jdbi jdbi]
(.open jdbi))
尝试使用库时:
alavita.core=> (def c (dao/create "jdbc:sqlite:/tmp/data.db"))
#'alavita.core/c
alavita.core=> (def h (dao/open c))
#'alavita.core/h
alavita.core=> (.execute h "show tables")
IllegalArgumentException No matching method found: execute for class org.jdbi.v3.core.Handle clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
这有点奇怪,因为 h 肯定有 .execute:
alavita.core=> (cli/all-methods h)
(.attach .begin .close .commit .createBatch .createCall .createQuery .createScript .createUpdate .execute .getConfig .getConnection .getExtensionMethod .getStatementBuilder .getTransactionIsolationLevel .inTransaction .isClosed .isInTransaction .isReadOnly .lambda$attach$3 .lambda$new$0 .lambda$useTransaction$1 .lambda$useTransaction$2 .prepareBatch .release .rollback .rollbackToSavepoint .savepoint .select .setConfig .setConfigThreadLocal .setExtensionMethod .setExtensionMethodThreadLocal .setReadOnly .setStatementBuilder .setTransactionIsolation .useTransaction)
不确定它会横向移动。
打开和创建的类型:
alavita.core=> (type (dao/create "jdbc:sqlite:/tmp/data.db"))
org.jdbi.v3.core.Jdbi
alavita.core=> (type (dao/open c))
org.jdbi.v3.core.Handle
添加反射:
alavita.core=> (set! *warn-on-reflection* true)
true
alavita.core=> (.execute h "show tables")
Reflection warning, /private/var/folders/nr/g50ld9t91c555dzv91n43bg40000gn/T/form-init767780595230125901.clj:1:1 - call to method execute can't be resolved (target class is unknown).
IllegalArgumentException No matching method found: execute for class org.jdbi.v3.core.Handle clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
【问题讨论】:
-
您的类型提示说
open接受一个Jdbi,并返回一个句柄,但错误和它诉诸反射的事实表明jdbi已经是一个手柄。错误提到open,而不是.exexute。 -
验证
Jdbi/create返回的内容。 -
嗯,从未使用过该 API,但查看文档后您的用法似乎正确。我会在
open中进行一些前/后类型检查。 -
@Carcigenicate 你说得对,我复制粘贴失败。实际上是执行它有问题。我修好了。
-
啊,我知道这是什么。这是因为
execute使用 var args。让我们看看我是否记得如何解决这个问题...