Elixir的世界是函数的世界. 这里没有对象, 没有实例. 在这种状况下, 我问我本身一个问题.git
我真的须要ORM吗?github
个人答案是: NO.数据库
我须要数据. 直接来自于数据库的纯粹的数据. 另外一个我思考的问题是:函数
我须要一个查询数据库的DSL吗?工具
答案一样是否认的: NO.post
其实, 咱们已经有了一个现成的数据库查询语言, SQL, 记得么?学习
若是我建立一个包含SQL的Elixir函数. 若是咱们像使用其余函数同样使用这个函数.code
咱们可使用Elixir的宏系统来达到这个目的. 同时也是一个学习Elixir宏的好机会.对象
为此我开始编写 Defql. Defql是一个简单的Elixir包, 它提供了一个方式用SQL语言来定义函数. 它是如何工做的?开发
这个包提供了一个defquery
宏. 用它能够定义包含SQL查询的Elixir函数. 好比:
defmodule UserQuery do use Defql defquery get_by_blocked(blocked) do "SELECT * FROM users WHERE blocked = $blocked" end end
看起来很是干净整洁, 易于阅读. 而且最有用的是, 它支持参数.
调用这类函数也是很是简单的. 取决于给定的参数, 咱们能够锁定/解锁用户.
UserQuery.get_user(false) # => {:ok, []} UserQuery.get_user(true) # => {:ok, []}
这个包还包含其余的宏, 看一下这个例子:
defmodule UserQuery do use Defql defselect get(conds), table: :users definsert add(params), table: :users defupdate update(params, conds), table: :users defdelete delete(conds), table: :users end
这些宏将会床公共的CRUD函数. 所以没必要编写每个SQL查询. 如何调用他们?
UserQuery.get(id: "3") # => {:ok, [%{...}]} UserQuery.add(name: "Smbdy") # => {:ok, [%{...}]} UserQuery.update([name: "Other"], [id: "2"]) # => {:ok, [%{...}]} UserQuery.delete(id: "2") # => {:ok, [%{...}]}
配置也是一个简单的工做. 如今你能够用两种方式使用它.
使用现有的Ecto链接:
config :defql, connection: [ adapter: Defql.Adapter.Ecto.Postgres, repo: Taped.Repo ]
做为一个独立的链接
config :defql, connection: [ hostname: "localhost", username: "username", password: "password" database: "dbname", pool: DBConnection.Poolboy, pool_size: 1 ]
固然, 它还在很是早期的开发阶段. 可是postgres
支持得很好. 下面是缺乏的部分:
MySQL支持
IN
的支持
Ecto 适配器
支持数据库错误
使用 Defql, 咱们有一个很是干净, 简单和强大的方式与数据库交互.
这个工具库特别适合于在团队内有DBA的状况下使用, DBA已经帮你写好了全部的业务SQL, 你只须要把SQL参数化就能够了, 不用本身写数据操做相关的功能的时候特别有用也特别好维护. 若是团队内没有DBA, 仍是建议使用Ecto这类的的库.