的优势后而支付的新一代数据库访问层,上面介绍打造 api 时与数据库连接的艺术

概述

介绍了 api 的种种写法之后,下边介绍打造 api 时与数据库连接的法子。

上面采纳的工程的一体化代码已经公开在:
http://git.oschina.net/wangyubin/phoenix-api

概述

介绍了 api 的种种写法之后,上面介绍创设 api 时与数据库连接的艺术。

上面采取的工程的一体化代码已经了然在:
http://git.oschina.net/wangyubin/phoenix-api

ecto 简介

ecto 其实是独自于 phoenix framework 的,它是 elixir
语言达成的用来访问数据库的框架,类似于 ORM 然而和传统的 ORM
又有些不平等。 可以那样通晓,它是使用了 elixir
语言的动态性和函数式的特点,参考了价值观的 ORM
的优势后而支出的新一代数据库访问层。

ecto 简介

ecto 其实是单身于 phoenix framework 的,它是 elixir
语言已毕的用来访问数据库的框架,类似于 ORM 不过和观念的 ORM
又有点不雷同。 可以这么清楚,它是运用了 elixir
语言的动态性和函数式的表征,参考了观念的 ORM
的优势后而支付的新一代数据库访问层。

ecto 的三个根本组件

  1. Ecto.Repo 数据库包装器, 通过它可以执行数据库的增删改查,
    通过它配备数据库连接
  2. Ecto.Schema 那是 ORM 的基本,定义了操作对象和尾部数据库表之间的照耀
  3. Ecto.Changeset 那是 Ecto 的一个翻新的地点,在 Changeset
    中,可以定义校验数据层合法性的主意,在真的写入数据库此前,对数据举办校验
  4. Ecto.Query 以 elixir 语法编写的查询,能够幸免 SQL 注入等大面积难点

ecto 的四个关键组件

  1. Ecto.Repo 数据库包装器, 通过它可以执行数据库的增删改查,
    通过它配置数据库连接
  2. Ecto.Schema 那是 ORM 的着力,定义了操作对象和尾部数据库表之间的炫耀
  3. Ecto.Changeset 那是 Ecto 的一个更新的地方,在 Changeset
    中,可以定义校验数据层合法性的办法,在真正写入数据库此前,对数据开展校验
  4. Ecto.Query 以 elixir 语法编写的查询,可防止止 SQL 注入等大规模难题

ecto 使用示例

ecto 使用示例

创建示范工程

  • 新建工程

    $ mix new ecto_sample

  • 添加信赖 (mix.exs)

    defp deps do
    [

    {:postgrex, ">= 0.0.0"},
    {:ecto, "~> 2.0.0"}
    

    ]
    end

  • 设置使用音讯 (mix.exs)

    def application do
    [applications: [:logger, :postgrex, :ecto]]
    end

  • 得到看重包

    $ mix deps.get

创办示范工程

  • 新建工程

    $ mix new ecto_sample

  • 添加看重 (mix.exs)

    defp deps do
    [

    {:postgrex, ">= 0.0.0"},
    {:ecto, "~> 2.0.0"}
    

    ]
    end

  • 设置使用音讯 (mix.exs)

    def application do
    [applications: [:logger, :postgrex, :ecto]]
    end

  • 得到信赖包

    $ mix deps.get

数据库连接配置

# vi config/config.exs
config :ecto_sample, ecto_repos: [EctoSample.Repo]

config :ecto_sample, EctoSample.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "ecto_sample",
  username: "iotalab",
  password: "iotalab",
  hostname: "localhost"

安插好数据库连接之后,就足以在指令行下创设数据库了

$ mix ecto.create

数据库连接配置

# vi config/config.exs
config :ecto_sample, ecto_repos: [EctoSample.Repo]

config :ecto_sample, EctoSample.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "ecto_sample",
  username: "iotalab",
  password: "iotalab",
  hostname: "localhost"

配备好数据库连接之后,就足以在指令行下创制数据库了

$ mix ecto.create

创建 model 和 migration 代码

率先,通过命令行创造一个用来生成表的的 users module。

$ mix ecto.gen.migration users

本条命令会在 priv/repo/migrations 下自动生成 migration
脚本,只不过脚本是空的。 下边先创建 users 表的情节,然后填充 migration
脚本的情节

# vi lib/ecto_models.ex
defmodule EctoSample.User do
  use Ecto.Schema

  schema "users" do
    field :name, :string
    field :password, :string
    field :age, :integer

    timestamps
  end
end

# vi priv/repo/migrations/20160912131700_users.exs  这个文件是由上一条命令产生的
defmodule EctoSample.Repo.Migrations.Users do
  use Ecto.Migration

  def up do
    create table(:users) do
      add :name, :string
      add :password, :string
      add :age, :integer
      timestamps
    end
  end

  def down do
    drop table(:users)
  end
end

创建 model 和 migration 代码

率先,通过命令行创设一个用来生成表的的 users module。

$ mix ecto.gen.migration users

本条命令会在 priv/repo/migrations 下自动生成 migration
脚本,只然而脚本是空的。 上边先成立 users 表的内容,然后填充 migration
脚本的情节

# vi lib/ecto_models.ex
defmodule EctoSample.User do
  use Ecto.Schema

  schema "users" do
    field :name, :string
    field :password, :string
    field :age, :integer

    timestamps
  end
end

# vi priv/repo/migrations/20160912131700_users.exs  这个文件是由上一条命令产生的
defmodule EctoSample.Repo.Migrations.Users do
  use Ecto.Migration

  def up do
    create table(:users) do
      add :name, :string
      add :password, :string
      add :age, :integer
      timestamps
    end
  end

  def down do
    drop table(:users)
  end
end

创设数量库表

开创命令极度简单

$ mix ecto.migrate

创办数量库表

创建命令非常简单

$ mix ecto.migrate

动用示例

开创了一个粗略的表之后,就能够在命令行下测试是还是不是足以操作数据库了。
上面演示了增产一个 user 和 删除一个 user 的历程。

$ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> u = %EctoSample.User{name: "wyb", password: "passwd", age: 33}
%EctoSample.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, age: 33,
 id: nil, inserted_at: nil, name: "wyb", password: "passwd", updated_at: nil}


iex(2)> EctoSample.Repo.insert(u)

22:09:51.433 [debug] QUERY OK db=4.4ms
INSERT INTO "users" ("age","name","password","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [33, "wyb", "passwd", {{2016, 9, 12}, {14, 9, 51, 0}}, {{2016, 9, 12}, {14, 9, 51, 0}}]
{:ok,
 %EctoSample.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, age: 33,
  id: 3, inserted_at: #Ecto.DateTime<2016-09-12 14:09:51>, name: "wyb",
  password: "passwd", updated_at: #Ecto.DateTime<2016-09-12 14:09:51>}}


iex(3)> u = %EctoSample.User{id: 3}
%EctoSample.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, age: nil,
 id: 3, inserted_at: nil, name: nil, password: nil, updated_at: nil}


iex(4)> EctoSample.Repo.delete(u)

22:11:28.960 [debug] QUERY OK db=3.4ms
DELETE FROM "users" WHERE "id" = $1 [3]
{:ok,
 %EctoSample.User{__meta__: #Ecto.Schema.Metadata<:deleted, "users">, age: nil,
  id: 3, inserted_at: nil, name: nil, password: nil, updated_at: nil}}

动用示例

开创了一个简易的表之后,就足以在指令行下测试是还是不是可以操作数据库了。
下边演示了增产一个 user 和 删除一个 user 的进度。

$ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> u = %EctoSample.User{name: "wyb", password: "passwd", age: 33}
%EctoSample.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, age: 33,
 id: nil, inserted_at: nil, name: "wyb", password: "passwd", updated_at: nil}


iex(2)> EctoSample.Repo.insert(u)

22:09:51.433 [debug] QUERY OK db=4.4ms
INSERT INTO "users" ("age","name","password","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [33, "wyb", "passwd", {{2016, 9, 12}, {14, 9, 51, 0}}, {{2016, 9, 12}, {14, 9, 51, 0}}]
{:ok,
 %EctoSample.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, age: 33,
  id: 3, inserted_at: #Ecto.DateTime<2016-09-12 14:09:51>, name: "wyb",
  password: "passwd", updated_at: #Ecto.DateTime<2016-09-12 14:09:51>}}


iex(3)> u = %EctoSample.User{id: 3}
%EctoSample.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, age: nil,
 id: 3, inserted_at: nil, name: nil, password: nil, updated_at: nil}


iex(4)> EctoSample.Repo.delete(u)

22:11:28.960 [debug] QUERY OK db=3.4ms
DELETE FROM "users" WHERE "id" = $1 [3]
{:ok,
 %EctoSample.User{__meta__: #Ecto.Schema.Metadata<:deleted, "users">, age: nil,
  id: 3, inserted_at: nil, name: nil, password: nil, updated_at: nil}}

补充表达

除开修改下面的文件之外,还有上面2个位置必要修改,否则 EctoSample
模块不会加载:

# vi lib/ecto_sample.ex
defmodule EctoSample do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(EctoSample.Repo, []),
    ]
    opts = [strategy: :one_for_one, name: EctoTest.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

def application do
  [applications: [:logger, :postgrex, :ecto],
   mod: {EctoSample, []}]   # <===  IMPORTANT !!!
end

补偿表达

除去修改上边的文本之外,还有下边2个地点要求修改,否则 EctoSample
模块不会加载:

# vi lib/ecto_sample.ex
defmodule EctoSample do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(EctoSample.Repo, []),
    ]
    opts = [strategy: :one_for_one, name: EctoTest.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

def application do
  [applications: [:logger, :postgrex, :ecto],
   mod: {EctoSample, []}]   # <===  IMPORTANT !!!
end

api with postgresql

api with postgresql

postgresql 安装与配置

以下安装配置是依据 CentOS7 的

# 安装 package
$ sudo yum install postgresql-server

# init db
$ sudo su - postgres
$ initdb -D /var/lib/pgsql/data

# start db
$ sudo systemctl start postgresql

# create user and database
$ sudo su - postgres
$ psql -U postgres -W       # password is also "postgres"
postgres=# CREATE USER iotalab WITH PASSWORD 'iotalab';
postgres=# CREATE DATABASE test OWNER iotalab ENCODING 'UTF8';

安装可以局域网内访问

$ sudo su - postgres 
$ cd /var/lib/pgsql/data

vim pg_hba.conf

host    all             all             0.0.0.0/0            md5

vim postgresql.conf

listen_addresses = '*'

长途连接不上时试试禁用 iptables

$ sudo systemctl stop iptables

postgresql 安装与配置

以下安装配备是依据 CentOS7 的

# 安装 package
$ sudo yum install postgresql-server

# init db
$ sudo su - postgres
$ initdb -D /var/lib/pgsql/data

# start db
$ sudo systemctl start postgresql

# create user and database
$ sudo su - postgres
$ psql -U postgres -W       # password is also "postgres"
postgres=# CREATE USER iotalab WITH PASSWORD 'iotalab';
postgres=# CREATE DATABASE test OWNER iotalab ENCODING 'UTF8';

设置可以局域网内访问

$ sudo su - postgres 
$ cd /var/lib/pgsql/data

vim pg_hba.conf

host    all             all             0.0.0.0/0            md5

vim postgresql.conf

listen_addresses = '*'

远程连接不上时试试禁用 iptables

$ sudo systemctl stop iptables

始建 数据库和表

  1. 给那么些工程加上 数据库的襄助其实创立的工程的时候,默许就是永葆数据库的。可是前边的演示不须求数据库,所以成立那几个工程的时候用了
    –no-ecto 的参数。
    重新创造工程,并将已写的代码复制进去即可,这一次成立工程时不加
    –no-ecto 参数。

    $ mix phoenix.new phoenix_api
    
  2. 布署数据库连接并创办数据库 修改文件 config/dev.exs

    # Configure your database
    config :phoenix_api, PhoenixApi.Repo,
      adapter: Ecto.Adapters.Postgres,
      username: "iotalab",
      password: "iotalab",
      database: "dev_db",
      hostname: "localhost",
      pool_size: 10
    

    创制数据库

    $ mix ecto.create
    
  3. 开创一张用来测试的表

    $ mix phoenix.gen.model User users name:string email:string age:integer
    * creating web/models/user.ex
    * creating test/models/user_test.exs
    * creating priv/repo/migrations/20160913230129_create_user.exs
    

    查看生成的文书,已经依照命令行的中参数,生成了相应的对象,可以窥见里头自动添加了
    timestamps 方法,那个法子是机动抬高一些 updated_at, inserted_at
    等通用时间字段。 然后透过命令行创建表:

    $  mix ecto.migrate
    
    07:10:52.527 [info]  == Running PhoenixApi.Repo.Migrations.CreateUser.change/0 forward
    
    07:10:52.527 [info]  create table users
    
    07:10:52.537 [info]  == Migrated in 0.0s
    

创立 数据库和表

  1. 给这一个工程加上 数据库的支撑
    其实创建的工程的时候,默许就是支撑数据库的。不过前边的以身作则不必要数据库,所以创造那一个工程的时候用了
    –no-ecto 的参数。
    重新创立工程,并将已写的代码复制进去即可,这一次成立工程时不加
    –no-ecto 参数。

    $ mix phoenix.new phoenix_api
    
  2. 安顿数据库连接并制造数据库 修改文件 config/dev.exs

    # Configure your database
    config :phoenix_api, PhoenixApi.Repo,
      adapter: Ecto.Adapters.Postgres,
      username: "iotalab",
      password: "iotalab",
      database: "dev_db",
      hostname: "localhost",
      pool_size: 10
    

    创办数据库

    $ mix ecto.create
    
  3. 成立一张用来测试的表

    $ mix phoenix.gen.model User users name:string email:string age:integer
    * creating web/models/user.ex
    * creating test/models/user_test.exs
    * creating priv/repo/migrations/20160913230129_create_user.exs
    

    翻看生成的公文,已经依照命令行的中参数,生成了相应的对象,可以窥见里头自动添加了
    timestamps 方法,这几个艺术是自行抬高一些 updated_at, inserted_at
    等通用时间字段。 然后透过命令行创设表:

    $  mix ecto.migrate
    
    07:10:52.527 [info]  == Running PhoenixApi.Repo.Migrations.CreateUser.change/0 forward
    
    07:10:52.527 [info]  create table users
    
    07:10:52.537 [info]  == Migrated in 0.0s
    

增删改查 示例

在测试代码中构造了 增删改查 的测试 case,然后用 mix test
命令来展开测试。
具体代码可以参见:http://git.oschina.net/wangyubin/phoenix-api/blob/master/test/models/user_test.exs

增删改查 示例

在测试代码中构造了 增删改查 的测试 case,然后用 mix test
命令来拓展测试。
具体代码可以参见:http://git.oschina.net/wangyubin/phoenix-api/blob/master/test/models/user_test.exs

总结

采纳 ecto 模块,操作数据库极度简单,可是,写岀良好 api 的要害依然在于
api
的宏图上,学习这些框架的意义是在乎把一部分通用繁琐的劳作交给框架来处理,可以让大家把关键的生命力放在工作代码的营造上。

时至今天,phoenix framework api 连串的3篇也终结了。

来源:http://blog.iotalabs.io/

总结

采用 ecto 模块,操作数据库卓殊简单,不过,写岀良好 api 的要紧照旧在于
api
的统筹上,学习那些框架的意思是在乎把一部分通用繁琐的劳作付出框架来处理,可以让我们把首要的生命力放在工作代码的营造上。

至此,phoenix framework api 连串的3篇也甘休了。

来源:http://blog.iotalabs.io/

相关文章