导读:本期聚焦于小伙伴创作的《SQL语言如何与Elixir交互?SQL语言在Phoenix框架中的Ecto应用是怎样的》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL语言如何与Elixir交互?SQL语言在Phoenix框架中的Ecto应用是怎样的》有用,将其分享出去将是对创作者最好的鼓励。

在Elixir的Phoenix框架开发中,数据库操作是核心需求之一,而SQL语言作为关系型数据库的标准操作语言,和Elixir的交互主要通过Ecto库实现。Ecto提供了一套领域特定语言,让开发者可以用Elixir的语法编写数据库操作逻辑,无需直接拼接原生SQL,同时也支持在需要时执行原生SQL语句。

SQL语言如何与Elixir交互?SQL语言在Phoenix框架中的Ecto应用是怎样的

Ecto的核心组件

Ecto主要包含四个核心模块,分别承担不同的职责:

  • Repo:数据库仓库,负责和数据库建立连接,执行所有的数据库操作命令,是Ecto和数据库交互的入口。
  • Schema:用于映射数据库表结构,定义表的字段、类型以及字段的校验规则,是Elixir代码和数据库表的对应桥梁。
  • Changeset:用于处理数据变更,包含数据校验、脏数据过滤、关联数据处理等逻辑,保证写入数据库的数据符合预期。
  • Query:用于构建查询语句,支持用Elixir的管道语法组合查询条件,最终会被Ecto转换成对应的SQL语句执行。

基础CRUD操作的Ecto实现

下面通过一个用户表的例子,展示如何通过Ecto完成基础的增删改查操作,这些操作会被Ecto转换成对应的SQL语句执行。

定义Schema

首先定义用户表的Schema,映射数据库中的users表:

# lib/my_app/accounts/user.ex
defmodule MyApp.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset

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

    timestamps()
  end

  # 定义数据变更校验规则
  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :email, :age])
    |> validate_required([:name, :email])
    |> validate_format(:email, ~r/@/)
    |> validate_number(:age, greater_than_or_equal_to: 0)
    |> unique_constraint(:email)
  end
end

配置Repo

在config/dev.exs中配置数据库连接信息,Repo会读取这些配置建立数据库连接:

# config/dev.exs
config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "my_app_dev",
  username: "postgres",
  password: "postgres",
  hostname: "localhost",
  port: 5432

执行CRUD操作

通过Repo执行对应的操作,Ecto会自动生成SQL语句:

# 插入数据
alias MyApp.Accounts.User
alias MyApp.Repo

# 创建用户,Ecto会生成INSERT INTO users (name, email, age) VALUES ($1, $2, $3) RETURNING id, name, email, age, inserted_at, updated_at的SQL
user_attrs = %{name: "张三", email: "zhangsan@ipipp.com", age: 25}
changeset = User.changeset(%User{}, user_attrs)
case Repo.insert(changeset) do
  {:ok, user} -> IO.inspect(user, label: "插入成功")
  {:error, changeset} -> IO.inspect(changeset.errors, label: "插入失败")
end

# 查询数据,Ecto会生成SELECT u0.id, u0.name, u0.email, u0.age, u0.inserted_at, u0.updated_at FROM users AS u0 WHERE (u0.email = $1)的SQL
user = Repo.get_by(User, email: "zhangsan@ipipp.com")
IO.inspect(user, label: "查询结果")

# 更新数据
changeset = User.changeset(user, %{age: 26})
case Repo.update(changeset) do
  {:ok, user} -> IO.inspect(user, label: "更新成功")
  {:error, changeset} -> IO.inspect(changeset.errors, label: "更新失败")
end

# 删除数据,Ecto会生成DELETE FROM users WHERE id = $1的SQL
Repo.delete(user)

执行原生SQL语句

如果遇到Ecto的Query无法覆盖的复杂SQL场景,也可以直接通过Repo执行原生SQL语句:

# 执行查询类原生SQL,返回结果是列表,每个元素是元组
result = Repo.query!("SELECT id, name, email FROM users WHERE age > $1", [20])
Enum.each(result.rows, fn row ->
  IO.inspect(row, label: "原生SQL查询结果")
end)

# 执行修改类原生SQL,比如批量更新
Repo.query!("UPDATE users SET age = age + 1 WHERE age < $1", [30])

Ecto和原生SQL的选择建议

日常开发中,优先使用Ecto提供的CRUD和Query API,这样不仅能减少SQL注入风险,还能利用Ecto的校验、关联处理等能力。只有在遇到非常复杂的查询、数据库特有的函数调用等场景时,再考虑使用原生SQL,同时要注意原生SQL的参数化,避免直接拼接字符串导致安全问题。

ElixirEctoPhoenixSQL数据库交互修改时间:2026-05-27 23:10:55

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。