ClojureQL 与 clojure.contrib.sql 相比如何?
看起来每个案例都很好地涵盖了基本案例,例如选择某些列和按谓词过滤,但我想知道每个案例如何比较更高级的案例。与另一种相比,用一种方式表达复杂的查询是否更容易?一个库是否缺少另一个库所涵盖的任何功能?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ClojureQL 和 clojure.contrib.sql 是两个完全不同的库。第一个目标是实现关系代数的原语并将其编译为 SQL92。它还提供了一个可扩展的编译器,可以适应数据库特定的 SQL 方言。第二个是一组轻量级帮助器,用于从 Clojure 代码使用 JDBC。
查询
clojure.contib.sql
使用clojure.contib.sql,您必须使用SQL 来编写查询。下面是一个示例:
ClojureQL
由于 ClojureQL 主要是一种查询语言,因此它提供了丰富的基于 Clojure 的 DSL 来创建 SQL 查询。我将跳过高级示例,只向您展示与上述查询等效的 ClojureQL:
您可以使用两者来表达任意复杂度的查询,但 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!
的快捷方式这些具有使用 ClojureQL 谓词语法的优点,但目前 ClojureQL 的这一部分不会生成与数据库无关的 SQL,因为它与编译器分离。我打算通过合并我在不久的将来编写的另一个库中的代码来解决这个问题。
模式操作
clojure.contib.sql
clojure.contrib.sql 仅提供
create-table
和drop-table
用于创建和删除表。请注意,这些都是非常简单的函数,不会使您的代码具有可移植性。要更改表,您需要使用do-commands
函数发送 SQLALTER
语句。ClojureQL
未提供模式操作助手。
Lobos(无耻的插件;-)
这是我编写的一个库,用于填补这两个库留下的漏洞。这是一项正在进行的工作,但您已经获得了 Clojure DSL,可以以与数据库无关的方式发送任何 DDL 语句。
以下是创建表的基本示例:
并更改它:
您可以通过访问网站<获得有关此库的更多信息/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:
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:
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 aRTable
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.
(insert-records table & records)
, where records are maps(insert-rows table & rows)
, where rows are vectors(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 provides three
RTable
methods to manipulate the specified table data:conj!
which is a shorcut to contrib.sql'sinsert-records
disj!
which is a shorcut to contrib.sql'sdelete-rows
update-in!
which is similar to contrib.sql'supdate-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
anddrop-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 SQLALTER
statements using thedo-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:
And altering it:
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.