phoenix学习笔记(ecto)
- Ecto有四个组件:
- Ecto.Repo 数据库的定义, 在config.exs里
- Ecto.Schema map数据到elixir结构
- Ecto.Changeset 在任何记录发生改变时,validate一下
- Ecto.Query 查询
- 设置configuration:mix ecto.gen.repo -r Friends.Repo
- 在配置文件config/config.exs里对数据库进行配置:
config :friends, Friends.Repo, database: "friends_repo", username: "user", password: "pass", hostname: "localhost"
- 创建数据库:mix ecto.create
- priv/repo/migrations里,可以设置数据库的结构:
defmodule Friends.Repo.Migrations.CreatePeople do use Ecto.Migration def change do create table(:people) do add :first_name, :string add :last_name, :string add :age, :integer end end end
创建数据库里的表结构:mix ecto.migrate
如果觉得刚才的表结构有问题,回滚:mix ecto.rollback
- 在lib/friends/person.ex里创建schema(代表数据库的数据结构):
defmodule Friends.Person do use Ecto.Schema schema "people" do field :first_name, :string field :last_name, :string field :age, :integer end end
在iex里:person = %Friends.Person{} 或者person = %Friends.Person{age: 28} 创建一个新的struct。可以用schema和数据库进行交互。如Repo.insert!(person),会返回他的id(主键)注意:不加!会出错。 eg2: Repo.delete!(person) 删除刚才的记录
- Ecto.changest:
def changeset(user, params \\ %{}) do user |> cast(params, [:name, :email, :age]) |> validate_required([:name, :email]) |> validate_format(:email, ~r/@/) |> validate_inclusion(:age, 18..100) end
cast function里:会返回一个 changeset, 所列的参数是后面要用到的(validate)。
- association:
has_many
belongs_to
在使用时,可以用preload,有三种用法
Repo.all from p in Post, preload: [:comments]
Repo.all from p in Post, join: c in assoc(p, :comments), where: c.votes > p.votes, preload: [comments: c]
posts = Repo.all(Post) |> Repo.preload(:comments)
Ecto模块也提供一些方法如: Ecto.assoc/2
returns a query with all associated data to a given struct:
import Ecto # Get all comments for the given post Repo.all assoc(post, :comments) # Or build a query on top of the associated comments query = from c in assoc(post, :comments), where: not is_nil(c.title) Repo.all(query)
build_assoc/3
, which allows someone to build an associated struct with the proper fields:
详情查看官方文档。
注意一点:Ecto 要使用ecto.create
and ecto.migrate,必须先定义
:ecto_repos:
config :my_app, :ecto_repos, [MyApp.Repo] config :my_app, MyApp.Repo, database: "ecto_simple", username: "postgres", password: "postgres", hostname: "localhost"
1.插入记录:
person = %Friends.Person{}
Friends.Repo.insert(person)
2.对记录进行校对:
def changeset(person, params \\ %{}) do person |> Ecto.Changeset.cast(params, [:first_name, :last_name, :age]) |> Ecto.Changeset.validate_required([:first_name, :last_name]) end
person = %Friends.Person{}
changeset = Friends.Person.changeset(person, %{})
Friends.Repo.insert(changeset)
changeset.valid? 可判断校对正确与否
3.查询第一条记录
Friends.Person |> Ecto.Query.first |> Friends.Repo.one
4.查询所有记录
Friends.Person |> Friends.Repo.all
5.根据id获取记录
Friends.Person |> Friends.Repo.get(1)
6.根据属性获取记录
Friends.Person |> Friends.Repo.get_by(first_name: "Ryan")
Friends.Person |> Ecto.Query.where(last_name: "Smith") |> Friends.Repo.all
7.从查询的记录中查询
query = Friends.Person |> Ecto.Query.where(last_name: "Smith")
query = query |> Ecto.Query.where(first_name: "Jane")
8.update记录
person = Friends.Person |> Ecto.Query.first |> Friends.Repo.one
changeset = Friends.Person.changeset(person, %{age: 29})
Friends.Repo.update(changeset)
9.删除记录
person = Friends.Repo.get(Friends.Person, 1)
Friends.Repo.delete(person)