ClojureQL 与 clojure.contrib.sql 相比如何?

发布于 2024-10-15 12:30:49 字数 105 浏览 2 评论 0原文

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

It looks like each one covers the basic cases like selecting certain columns and filtering by predicate pretty well, but I'm wondering how each compares for more advanced cases. Is it easier to express complex queries in one vis-à-vis the other? Is one library missing any functionality that the other covers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧梦荧光笔 2024-10-22 12:30:49

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

插入、更新和删除

clojure.contib.sql

clojure.contrib.sql 提供了一组全面的函数来插入、更新和删除行。

  • 插入
    • (插入记录表和记录),其中记录是映射
    • (insert-rows table & rows),其中行是向量
    • (插入值表列名称和值组)
  • 更新(update-values 表 where-params 记录)
  • 插入 > 或更新(更新或插入值表,其中参数记录)
  • 删除(删除行表,其中-params)

ClojureQL

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

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

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

模式操作

clojure.contib.sql

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

ClojureQL

未提供模式操作助手。

Lobos(无耻的插件;-)

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

以下是创建表的基本示例:

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

并更改它:

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

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

其他

clojure.contrib.sql 有一些额外的低级帮助程序,请参阅 完整文档

关于这些库如何处理数据库连接还有更多要说的,但我将改天再讲!

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

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

ClojureQL and clojure.contrib.sql are two quite different libraries. The first aims to implement the primitives from relational algebra and compile those to SQL92. It also offer an extensible compiler that can be adapted to database specific SQL dialect. The second is a lightweight set of helpers for using JDBC from Clojure code.

Querying

clojure.contib.sql

With clojure.contib.sql, you'll have to use SQL to write your queries. Here's an example:

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

ClojureQL

As ClojureQL is mostly a query language, it provides a rich Clojure-based DSL to create SQL queries. I'll skip advanced examples and only show you the ClojureQL equivalent to the above query:

(sql/with-connection db
  (cql/with-results [rs (cql/table :customer)]
    (doseq [r rs] (println (:lastname r))))

You can express queries of arbitrary complexity with both, but contrib.sql require you to write SQL code. Take note that ClojureQL DSL main advantage over standard SQL is composability. Its table function returns a RTable object representing a query on the specified table, you can chain other ClojureQL function over that object to create the query that you need, then dereference it to execute it. Refer to ClojureQL examples page and documentation for more information on how to create more complex queries.

Inserting, Updating and Deleting

clojure.contib.sql

clojure.contrib.sql provides a comprehensive set of functions to insert, update and delete rows.

  • Inserting:
    • (insert-records table & records), where records are maps
    • (insert-rows table & rows), where rows are vectors
    • (insert-values table column-names & value-groups)
  • Updating: (update-values table where-params record)
  • Inserting or Updating: (update-or-insert-values table where-params record)
  • Deleting: (delete-rows table where-params)

ClojureQL

ClojureQL provides three RTable methods to manipulate the specified table data:

  • conj! which is a shorcut to contrib.sql's insert-records
  • disj! which is a shorcut to contrib.sql's delete-rows
  • update-in! which is similar to contrib.sql's update-or-insert-values

These have the advantage of using ClojureQL predicates syntax, but for now this part of ClojureQL is not generating database agnostic SQL as it's separated from the compiler. I intend to fix that by merging code from another library I've written in the more-or-less near future.

Schema Manipulation

clojure.contib.sql

clojure.contrib.sql only provides create-table and drop-table for creating and removing tables. Note that these are very simple functions that won't make your code portable. To alter a table you'll need to send SQL ALTER statements using the do-commands function.

ClojureQL

No schema manipulation helpers provided.

Lobos (shameless plug ;-)

This is a library I wrote to plug the hole left by these two libraries. It's a work in progress, but you already get a Clojure DSL to send any DDL statements in a database agnostic way.

Here's a basic example for creating a table:

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

And altering it:

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

You can get more information on this library by visiting the website or the github page. It aims to provides higher-level functionality like migrations and declarative schema manipulation.

Others

clojure.contrib.sql has a couple extra lower-level helpers, see the complete documentation

There's more to say about how these libraries handle database connections but I'll leave that for another day!

P.S.: Note that both ClojureQL and Lobos are relatively young libraries that still need some work. Both descent from the original ClojureQL project which was a DSL covering the whole SQL language. ClojureQL already have a stable API, but only provide a SQL92 compatible compiler. Lobos has compiler support for multiple databases. but is still in active development and its API can still change.

Update: I've made some changes after a suggestion from Lau. ClojureQL itself doesn't aim to be database-agnostic, but provide the means for users to replace the compiler by a database-specific one. Note that the DML part of SQL is much more standardize than the DDL part.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文