最初我会问我为什么在结果集上调用(seq)作为空虚测试时遇到问题,但是一些研究表明它显然是因为jdbc游标没有移动到任何地方。好又花花公子。如果我不知道它的名字,有没有办法在结果集上调用next()?我可以将它绑定到clojure中的符号,但我无法弄清楚如何从那里调用该方法。
编辑:如果不清楚,我指的是java resultSet方法next(),而不是clojure(下一个)
编辑#2这是一段代码:
(defn user-exists? [email]
(with-connection db
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(.next res)
(seq res))))
(感谢.next的帮助,顺便说一句......还没有做过多少java互操作)
但是,如果查询没有返回任何内容,则使用(seq)会抛出NullPointerException。我想知道是否有更清洁,惯用的方法来做到这一点?
答案 0 :(得分:3)
res将绑定到基于ResultSet的Clojure序列,其中每个项目是结果记录的映射,输出列名称作为键中的关键字。您无法访问基础实际ResultSet对象。
通常你根本不打电话。要成为惯用语Clojure,您将利用对序列(map,filter,reduce等)进行操作的庞大函数库来生成输出。在这里你可能会说:
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(map :guid res))
将适用:guid作为res seqeuence的函数并检索每个记录中guid的列值,返回所有guid的新序列。然后,您可以将该地图包装在过滤器或其他任何需要的地方。
在这种情况下,seq
应该是你想要的,但我认为抽象有点漏。当我尝试它时,我得到了 java.sql.SQLRecoverableException:Closed Resultset:next ,这意味着在抽象中过早地关闭了ResultSet。但是,我发现empty?
对这个用例没问题。
(defn user-exists? [email]
(with-connection db
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(.next res)
(not (empty? res)))))
这似乎是我在clojure.core / resultset-seq中的一个错误,我在这里报告为CLJ-676。
答案 1 :(得分:1)
怎么样
(defn user-exists? [email]
(with-connection db
(with-query-results res ["SELECT guid from users WHERE email=?" email]
(first res))))
如果返回一行,则返回某些内容;如果没有匹配的行,则返回nil
。
您之前的查询失败,因为res
是对(resultset-seq x)
的调用的值,因此您不能在其上使用Java ResultSet.next()
,也不想调用{{ 1}}再次上它。
如上所述,您必须在seq
(和resultset-seq
)打开时评估ResultSet
,因此您必须
Connection