Clojure读取Oracle几何数据为WKB字符串时遇连接关闭异常
解决 Clojure 读取 Oracle WKB 时的 Closed Connection 异常
这个问题我之前也碰到过,核心原因是 clojure.java.jdbc 默认会在查询完成后立即释放数据库连接,但你尝试读取BLOB流的操作是在连接关闭之后进行的,自然就会抛出连接关闭的异常了。
为什么会出错?
你的代码里,j/query执行完毕后,底层的数据库连接就被归还给连接池了。这时候再去调用.getBinaryStream()和.readAllBytes(),BLOB对象已经失去了连接上下文,所以报错。
两种简单的解决方案
方案1:让 JDBC 自动把 BLOB 转换成字节数组
clojure.java.jdbc 支持通过配置参数直接将BLOB类型映射为字节数组,这样查询结果里的:wkb直接就是你需要的字节数据,无需手动处理流:
(require '[clojure.java.jdbc :as j]) ;; 直接在 query 中指定 :blob-type 选项 (->> (j/query db "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb from t where idf = 1" {:blob-type :bytes}) (map :wkb))
方案2:在连接保持打开的状态下处理流
如果需要手动处理流(比如处理大BLOB),可以用j/with-db-connection来显式保持连接打开,直到你处理完所有结果:
(require '[clojure.java.jdbc :as j]) (j/with-db-connection [conn db] (->> (j/query conn "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb from t where idf = 1") (map (fn [row] ;; 使用 with-open 确保流被正确关闭 (with-open [blob-stream (:wkb row)] (.readAllBytes blob-stream))))))
小提示
推荐优先用方案1,因为它更简洁,也避免了手动管理流和连接的麻烦。如果是处理非常大的WKB数据,方案2可以让你更灵活地控制流的读取方式(比如分块读取)。
内容的提问来源于stack exchange,提问作者Bogdan
相关产品推荐
相关产品推荐

