25

看起来每个都涵盖了基本案例,例如选择某些列和按谓词过滤,但我想知道每个案例如何比较更高级的案例。用一个相对于另一个来表达复杂的查询是否更容易?一个库是否缺少另一个库所涵盖的任何功能?

4

1 回答 1

37

ClojureQL 和 clojure.contrib.sql 是两个完全不同的库。第一个旨在实现关系代数中的原语并将其编译为 SQL92。它还提供了一个可扩展的编译器,可以适应数据库特定的 SQL 方言。第二个是一组轻量级的帮助器,用于从 Clojure 代码中使用 JDBC。

查询

clojure.contib.sql

使用 clojure.contib.sql,您必须使用 SQL 来编写查询。这是一个例子:

(sql/with-connection db
  (sql/with-query-results rs ["select * from customer"]
    (doseq [r rs] (println (:lastname r))))

ClojureQL

由于 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 代码。请注意,与标准 SQL 相比,ClojureQL DSL 的主要优势在于可组合性。它的table函数返回一个RTable表示对指定表的查询的对象,您可以在该对象上链接其他 ClojureQL 函数以创建您需要的查询,然后取消引用它以执行它。有关如何创建更复杂查询的更多信息,请参阅 ClojureQL示例页面文档。

插入、更新和删除

clojure.contib.sql

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

ClojureQL 提供了三种RTable方法来操作指定的表数据:

  • conj!这是 contrib.sql 的快捷方式insert-records
  • disj!这是 contrib.sql 的快捷方式delete-rows
  • update-in!这类似于 contrib.sql 的update-or-insert-values

这些具有使用 ClojureQL 谓词语法的优势,但目前 ClojureQL 的这一部分不生成与数据库无关的 SQL,因为它与编译器分离。我打算通过合并我在不久的将来编写的另一个库的代码来解决这个问题。

模式操作

clojure.contib.sql

clojure.contrib.sql 仅提供create-tabledrop-table用于创建和删除表。请注意,这些是非常简单的功能,不会使您的代码可移植。要更改表,您需要使用该函数发送 SQLALTER语句。do-commands

ClojureQL

没有提供模式操作助手。

Lobos(无耻的插头;-)

这是我写的一个库,用来堵住这两个库留下的漏洞。这是一项正在进行的工作,但您已经获得了一个 Clojure DSL,可以以与数据库无关的方式发送任何 DDL 语句。

这是创建表的基本示例:

(create (table :users (integer :id :unique)))

并改变它:

(alter :add (table :users (text :name)))

您可以通过访问网站github 页面获取有关此库的更多信息。它旨在提供更高级别的功能,例如迁移和声明性模式操作。

其他

clojure.contrib.sql 有几个额外的低级助手,请参阅完整文档

关于这些库如何处理数据库连接还有更多要说的,但我将把它留到另一天!

PS:请注意,ClojureQL 和 Lobos 都是相对年轻的库,还需要一些工作。两者都源自最初的 ClojureQL 项目,该项目是一个涵盖整个 SQL 语言的 DSL。ClojureQL 已经有了稳定的 API,但只提供了一个兼容 SQL92 的编译器。Lobos 具有对多个数据库的编译器支持。但仍在积极开发中,其 API 仍可更改。

更新:在刘的建议下,我做了一些改变。ClojureQL 本身的目标不是与数据库无关,而是为用户提供一种方法,以用特定于数据库的编译器替换编译器。请注意,SQL 的 DML 部分比 DDL 部分标准化得多。

于 2011-02-04T07:26:25.923 回答