0Pricing
Go Academy · 课时

预处理语句

执行参数化查询

预处理语句 是 CoddyKit 上的免费 Go Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

什么是预处理语句

预处理语句会将 SQL 文本发送到数据库一次,以便解析和规划,然后使用不同参数执行多次。对于重复查询,它速度更快,也能更好地防止注入。

参数占位符

绝不要通过拼接用户输入来构建 SQL。请使用占位符,让驱动程序单独发送各个值。PostgreSQL 使用 $1, $2;MySQL 和 SQLite 使用 ?。

SELECT * FROM users WHERE age > $1 AND city = $2

为什么这样可以阻止注入

由于参数与 SQL 文本分开传输,数据库会严格将它们视为数据,而不会将其视为代码。恶意值如 " OR 1=1 会变成字面字符串,而不是可执行的 SQL。

db.Prepare

Prepare 会返回一个与连接池关联的 *sql.Stmt。然后您可以在该语句上调用 Exec 或 Query,并传入参数。

stmt, err := db.Prepare("INSERT INTO users(name, age) VALUES($1, $2)")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

执行语句

请为每个占位符提供参数,并调用 stmt.Exec。对于插入和更新操作,Exec 会返回一个 sql.Result,其中包含受影响的行数和最后插入的 ID。

res, err := stmt.Exec("Ada", 36)
if err != nil {
    log.Fatal(err)
}
n, _ := res.RowsAffected()
fmt.Println("inserted", n)

在循环中复用

性能提升来自复用:预处理一次,然后在循环中执行多次。数据库会在每次调用时复用已解析的执行计划。

for _, u := range users {
    if _, err := stmt.Exec(u.Name, u.Age); err != nil {
        log.Fatal(err)
    }
}

隐式预处理

直接向 db.Query 或 db.Exec 传入参数同样会安全地使用占位符;驱动程序可能会在底层执行预处理。显式调用 Prepare 主要适用于重复执行。

可运行的参数绑定模拟

真正的预处理语句需要数据库。这个可运行示例模拟安全的参数绑定,以展示值如何与查询文本保持分离。

package main

import "fmt"

func execPrepared(query string, args ...interface{}) string {
    return fmt.Sprintf("EXEC %q with args %v", query, args)
}

func main() {
    q := "INSERT INTO users(name, age) VALUES($1, $2)"
    people := [][2]interface{}{{"Ada", 36}, {"Lin", 41}}
    for _, p := range people {
        fmt.Println(execPrepared(q, p[0], p[1]))
    }
}

上下文变体

请使用 PrepareContext 和 stmt.ExecContext,使预处理调用遵守超时和取消操作,就像 database/sql 的其他部分一样。

始终关闭 Stmt

*sql.Stmt 会在数据库中持有资源。完成后请延迟调用 stmt.Close()。泄漏语句可能耗尽服务器端预处理语句的限制。

语句与连接池

在 *sql.DB 上准备的语句可以跨连接池中的连接工作;库会在该语句所使用的连接上重新准备它。通常您无需自行管理这一过程。

快速检查

请测试您对预处理语句的了解。

总结

您已经学会了预处理语句:

  • Prepare 只解析一次,可以执行多次
  • 占位符($1 或 ?)将值作为数据处理,从而阻止注入
  • stmt.Exec 返回受影响的行数;使用 defer stmt.Close()
  • 在循环中重复使用;使用上下文变体处理截止时间

常见问题解答

「预处理语句」课时是免费的吗?

是的 — 「预处理语句」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「预处理语句」这节课中我会学到什么?

执行参数化查询 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「预处理语句」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 打开连接
  2. 查询行
  3. 预处理语句
  4. 事务
← 返回 Go Academy