• phoenix 开发API系列(三)phoenix api 结合数据库


    概述

    介绍了 api 的各种写法之后,下面介绍构建 api 时与数据库连接的方式。

    下面使用的工程的完整代码已经公开在: http://git.oschina.net/wangyubin/phoenix-api

    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 使用示例

    创建示例工程

    • 新建工程
    $ 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
    

    创建 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
    

    使用示例

    创建了一个简单的表之后,就可以在命令行下测试是否可以操作数据库了。 下面演示了新增一个 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
    

    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
    

    创建 数据库和表

    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

    总结

    利用 ecto 模块,操作数据库非常简单,但是,写岀优秀 api 的关键还是在于 api 的设计上,学习这个框架的意义是在于把一些通用繁琐的工作交给框架来处理,可以让我们把主要的精力放在业务代码的构建上。

    至此,phoenix framework api 系列的3篇也结束了。

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

  • 相关阅读:
    requests 关于multipart/form-data类型上传文件
    APPIUM 小程序webview问题
    python多重继承,优先级
    关于apppium启动微信,每次都要重新登录的解决方法
    map函数
    unittest: if __name__ == "__main__" 理解
    接口自动化____如何根据测试数据excel中的数据量多少 去test类中定义同数据量的测试函数
    写一个简单的 django_post demo
    django day1 建立一个简答的django demo
    201903-1 分蛋糕
  • 原文地址:https://www.cnblogs.com/wang_yb/p/5871008.html
Copyright © 2020-2023  润新知