Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
未找到与JDBI和Clojure匹配的方法_Clojure_Jdbi - Fatal编程技术网

未找到与JDBI和Clojure匹配的方法

未找到与JDBI和Clojure匹配的方法,clojure,jdbi,Clojure,Jdbi,我有一个简单的方法: (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)

我有一个简单的方法:

(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肯定有。执行:

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)
如中所述,这是Java如何处理var args的问题。您需要首先将var arg包装到数组中,而不是依赖于var arg行为

我建议编写Clojure函数来处理此问题:

(defn execute [^Handle h, ^String sql, & args]
  (.execute h sql (into-array Object args)))

用它来代替

您的类型提示说,
open
接受一个Jdbi,并返回一个句柄,但是错误和它诉诸反射的事实表明,
Jdbi
已经是一个句柄了。错误提到的是
open
,而不是
。exexute
。请验证
Jdbi/create
返回的内容。嗯,从未使用过该API,但在查看文档后,您的用法似乎是正确的。我会在
open
@carcigenitate中做一些前/后类型检查,我有一个复制粘贴失败。它实际上是在执行时遇到问题的。我修好了。啊,我知道这是什么。这是因为
execute
使用var args。让我们看看我是否还记得如何解决这个问题……有趣的是,我刚刚把它排除了。(.execute h“show tables”(into array[])我在这个解决方案中遇到了这个问题:(into array[“/tmp”0])IllegalArgumentException数组元素类型不匹配java.lang.reflect.array.set(array.java:-2)@Istvan是否确实要将字符串和整数粘贴到同一数组中?否则如何才能插入到包含整数和文本字段的表中?@Istvan如果需要,请尝试
(插入数组对象[“/temp”0])
。如果元素的类型不同,则需要指定基类。