Теоретически вы можете использовать любой из методов clojure.contrib.sql / insert- * для вставки большого двоичного объекта, передавая большой двоичный объект в виде байтового массива, java.sql.Blob или объекта java.io.InputStream. На практике это зависит от водителя.
Для многих реализаций JDBC все вышеперечисленное работает должным образом, но если вы используете sqlitejdbc 0.5.6 из Clojars, вы обнаружите, что ваш BLOB-объект приведен к строке с помощью toString (). Все команды clojure.contrib.sql / insert- * выпускаются через clojure.contrib.sql / do-prepare, которое вызывает setObject () для java.sql.PreparedStatement. Реализация sqlitejdbc не обрабатывает setObject () ни для одного из типов данных BLOB-объектов, но по умолчанию приводит их к строке. Вот обходной путь, который позволяет хранить капли в SQLite:
(use '[clojure.contrib.io :only (input-stream to-byte-array)])
(require '[clojure.contrib.sql :as sql])
(defn my-do-prepared
"Executes an (optionally parameterized) SQL prepared statement on the
open database connection. Each param-group is a seq of values for all of
the parameters. This is a modified version of clojure.contrib.sql/do-prepared
with special handling of byte arrays."
[sql & param-groups]
(with-open [stmt (.prepareStatement (sql/connection) sql)]
(doseq [param-group param-groups]
(doseq [[index value] (map vector (iterate inc 1) param-group)]
(if (= (class value) (class (to-byte-array "")))
(.setBytes stmt index value)
(.setObject stmt index value)))
(.addBatch stmt))
(sql/transaction
(seq (.executeBatch stmt)))))
(defn my-load-blob [filename]
(let [blob (to-byte-array (input-stream filename))]
(sql/with-connection db
(my-do-prepared "insert into mytable (blob_column) values (?)" [blob]))))