看起来每个人都涵盖了基本情况,例如选择某些列并通过谓词过滤得很好,但我想知道每个列表如何比较更高级的案例。是否更容易在一个方面表达复杂的查询?一个库是否缺少对方涵盖的任何功能?
答案 0 :(得分:37)
ClojureQL和clojure.contrib.sql是两个完全不同的库。第一个目标是实现关系代数的原语并将其编译为SQL92。它还提供可扩展的编译器,可以适应数据库特定的SQL方言。第二个是一组轻量级帮助程序,用于使用Clojure代码中的JDBC。
使用clojure.contib.sql,您必须使用SQL来编写查询。这是一个例子:
(sql/with-connection db
(sql/with-query-results rs ["select * from customer"]
(doseq [r rs] (println (:lastname r))))
由于ClojureQL主要是查询语言,因此它提供了丰富的基于Clojure的DSL来创建SQL查询。我将跳过高级示例,只显示与上述查询等效的ClojureQL:
(sql/with-connection db
(cql/with-results [rs (cql/table :customer)]
(doseq [r rs] (println (:lastname r))))
您可以用两者表达任意复杂性的查询,但contrib.sql要求您编写SQL代码。请注意,ClojureQL DSL优于标准SQL的主要优点是可组合性。它的table
函数返回一个RTable
对象,表示对指定表的查询,你可以在该对象上链接其他ClojureQL函数来创建你需要的查询,然后取消引用它来执行它。有关如何创建更复杂查询的更多信息,请参阅ClojureQL examples page和documentation。
clojure.contrib.sql提供了一组全面的函数来插入,更新和删除行。
(insert-records table & records)
,其中记录是地图(insert-rows table & rows)
,其中行是向量(insert-values table column-names & value-groups)
(update-values table where-params record)
(update-or-insert-values table where-params record)
(delete-rows table where-params)
ClojureQL提供了三种RTable
方法来操作指定的表数据:
conj!
这是contrib.sql的insert-records
disj!
这是contrib.sql的delete-rows
update-in!
类似于contrib.sql的update-or-insert-values
这些具有使用ClojureQL谓词语法的优点,但是现在ClojureQL的这部分不会生成数据库不可知的SQL,因为它与编译器分离。我打算通过合并我在不久的将来编写的另一个库中的代码来解决这个问题。
clojure.contrib.sql仅提供create-table
和drop-table
来创建和删除表。请注意,这些是非常简单的功能,不会使您的代码可移植。要更改表,您需要使用ALTER
函数发送SQL do-commands
语句。
未提供架构操作助手。
这是我写的一个库,用于插入这两个库留下的漏洞。这是一项正在进行的工作,但您已经获得了Clojure DSL以数据库无关的方式发送任何DDL语句。
以下是创建表格的基本示例:
(create (table :users (integer :id :unique)))
改变它:
(alter :add (table :users (text :name)))
您可以访问website或github page获取有关此库的更多信息。它旨在提供更高级别的功能,如迁移和声明性模式操作。
clojure.contrib.sql有几个额外的低级助手,请参阅complete documentation
还有更多关于这些库如何处理数据库连接的说法,但我会留下另一天!
P.S。:请注意,ClojureQL和Lobos都是相对年轻的库,仍然需要一些工作。两者都来自最初的ClojureQL项目,这是一个覆盖整个SQL语言的DSL。 ClojureQL已经有了一个稳定的API,但只提供了SQL92兼容的编译器。 Lobos具有对多个数据库的编译器支持。但仍在积极开发中,其API仍然可以改变。
更新:经过Lau的建议,我做了一些更改。 ClojureQL本身并不旨在与数据库无关,而是为用户提供了通过特定于数据库替换编译器的方法。请注意,SQL的DML部分比DDL部分更加标准化。