ClojureQL如何与clojure.contrib.sql比较? [英] How does ClojureQL compare to clojure.contrib.sql?

查看:187
本文介绍了ClojureQL如何与clojure.contrib.sql比较?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

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))))
/ pre>

你可以用两个表达任意复杂性的查询,但contrib.sql需要你写SQL代码。注意ClojureQL DSL主要优于标准SQL的优点是可组合性它的 table 函数返回一个表示对指定表的查询的 RTable 对象,你可以链接其他ClojureQL函数对象创建所需的查询,然后取消引用以执行它。请参阅ClojureQL 示例页文档



clojure.contib .sql



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




  • 插入

    • (insert-records表&记录),其中记录是地图

    • (insert-rows table& rows)
    • (insert-values table column-names& value-groups)


  • 更新(update-values table where-params record)

  • 插入更新(update-or-insert-values表其中 - params记录)

  • 删除(delete-rows表其中 - 参数)



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-table drop-table 用于创建和删除表。注意,这些都是非常简单的功能,不会使你的代码可移植。要更改表,您需要使用 do-commands 函数发送SQL ALTER 语句。



ClojureQL



未提供模式操作辅助函数。



< h3> Lobos(无耻的插件; - )

这是我写的一个库,用来插入这两个库所剩下的洞。这是一个正在进行的工作,但你已经得到一个Clojure DSL以数据库不可知的方式发送任何DDL语句。



这是一个创建表的基本示例:

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

并修改它:

  :users(text:name)))

您可以通过访问< a href =http://budu.github.com/lobos/>网站或 github网页。它旨在提供更高级的功能,如迁移和声明式模式操作。



其他



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



还有更多关于这些库如何处理数据库连接的问题,但我会离开这一天!



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



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


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?

解决方案

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.

这篇关于ClojureQL如何与clojure.contrib.sql比较?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆