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這類的的庫.