phoenix 开发API系列(三)phoenix api 结合数据库
概述
介绍了 api 的各种写法之后,下面介绍构建 api 时与数据库连接的方式。
注 下面使用的工程的完整代码已经公开在: http://git.oschina.net/wangyubin/phoenix-api
ecto 简介
ecto 其实是独立于 phoenix framework 的,它是 elixir 语言实现的用来访问数据库的框架,类似于 ORM 但是和传统的 ORM 又有些不一样。 可以这么理解,它是利用了 elixir 语言的动态性和函数式的特性,参考了传统的 ORM 的优势后而开发的新一代数据库访问层。
ecto 的四个主要组件
- Ecto.Repo 数据库包装器, 通过它可以执行数据库的增删改查, 通过它配置数据库连接
- Ecto.Schema 这是 ORM 的核心,定义了操作对象和底层数据库表之间的映射
- Ecto.Changeset 这是 Ecto 的一个创新的地方,在 Changeset 中,可以定义校验数据层合法性的方法,在真正写入数据库之前,对数据进行校验
- 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
创建 数据库和表
给这个工程加上 数据库的支持 其实创建的工程的时候,默认就是支持数据库的。但是前面的示例不需要数据库,所以创建这个工程的时候用了 –no-ecto 的参数。 重新创建工程,并将已写的代码复制进去即可,这次创建工程时不加 –no-ecto 参数。
$ mix phoenix.new phoenix_api
配置数据库连接并创建数据库 修改文件 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
创建一张用来测试的表
$ 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篇也结束了。
phoenix 开发API系列(三)phoenix api 结合数据库的更多相关文章
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- WCF开发实战系列三:自运行WCF服务
WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...
- Web API系列(三)统一异常处理
前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...
- Kafka系列三 java API操作
使用java API操作kafka 1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...
- RabbitMQ系列(三)--Java API
基于java使用RabbitMQ 框架:SpringBoot1.5.14.RELEASE maven依赖: <dependency> <groupId>com.rabbitmq ...
- flask开发restful api系列(3)--利用alembic进行数据库更改
上面两章,主要讲基本的配置,今天我们来做一个比较有趣的东西,为每个客户加一个头像图片.如果我们图片保存在自己的服务器,对于服务器要求有点高,每次下载的时候,都会阻塞网络接口,要是1000个人同时访问这 ...
- Apache Kafka系列(三) Java API使用
Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka系列(三) Java API使用 摘要: Apache Kafka Java ...
- Hello Web API系列教程——Web API与国际化
软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...
- html5 canvas常用api总结(三)--图像变换API
canvas的图像变换api,可以帮助我们更加方便的绘画出一些酷炫的效果,也可以用来制作动画.接下来将总结一下canvas的变换方法,文末有一个例子来更加深刻的了解和利用这几个api. 1.画布旋转a ...
- 【开发者portal在线开发插件系列三】字符串 及 可变长度字符串
基础篇 基础场景见上面两个帖子,这里单独说明字符串和可变长度字符串的用法. 话不多说,开始今天的演(表)示(演) Profile和插件开发 添加一个string类型的属性: 在插件里添加一条数据上报消 ...
随机推荐
- 20151214study
An important quality of steel is its strength. (1)钢铁的最重要品质是其强度.She made a quick decision.她做了一个很快的决定. ...
- UI设计中px、pt、ppi、dpi、dp、sp之间的关系
UI设计中px.pt.ppi.dpi.dp.sp之间的关系 武汉AAA数字艺术教育 2015-07-24 14:19:50 职业教育 pi px 阅读(3398) 评论(0) 声明:本文由入驻搜狐公众 ...
- Spark简介
Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用并行框架,Spark,拥有Hadoop MapReduce所具有的优点:但不同于MapReduce的是 ...
- Rancher 快速上手指南操作(1)
Rancher 快速上手指南操作(1)该指南知道用户如何快速的部署Rancher Server 管理容器.前提是假设你的机器已经安装好docker了.1 确认 docker 的版本,下面是 ubunt ...
- HTTP协议-----小白
HTTP是一个属于应用层的面向对象的协议. ***OSI的7层从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层 HTTP协议的主要特点可概括如下: ...
- html5新特性之拖放
1.元素是否可拖动可放置 draggable="true" 设置元素可以拖动 ondragover="allowDrop(event)" 元素默认不能放置,加 ...
- 查询目前运行状态-CPU等情况
对目前的数据库的运行状况有一个基本的了解 ) DB_NAME(a.dbid) AS dbname , loginame , spid , cpu , b.text , lastwaittype , w ...
- 大数据通过PHP快速插入MYSQL的方法
如果您的mysql是通过brew安装的,那么请 vi /usr/local/Cellar/mysql/5.6.23/my.cnf 将 max_allowed_packet = 64M 写入保存并重启m ...
- Markdown示例
欢迎使用 Cmd Markdown 编辑阅读器 我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 -- 我们为记录思想 ...
- CRC 冗余校验计算
(1)设G(x)为r阶,则在信息位末尾加r个0形成新信息 r=原信息位数 - 1