sqlc 用于 Go:完整指南及示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

sqlc 用于 Go:从 SQL 生成类型安全代码

\n\n

sqlc 是一个编译器,它根据您的 SQL 查询生成 Go 代码。您无需手动编写与数据库交互的函数,只需编写纯 SQL,sqlc 就会为您生成类型化、安全且高效的函数。这与 ORM 有着根本的不同:您保留对 SQL 的完全控制,同时摆脱了编写样板代码的繁琐工作。

\n\n

为什么需要它?首先,sqlc 在编译时保证了类型安全。如果您更改了表结构或查询,sqlc 会重新生成代码,Go 编译器会立即指出所有需要修改的地方。其次,性能方面:生成的代码不使用反射,也不进行多余的内存分配,使其几乎与通过 database/sql 手动编写查询一样快。第三,它简化了代码审查:SQL 查询在 .sql 文件中清晰可见,而不是隐藏在 ORM 的方法中。

\n\n

sqlc 非常适合那些注重性能和查询控制的项目:高负载 API、金融系统、分析平台。它还能很好地与数据库迁移工具(例如 golang-migrate)配合使用,并且不绑定特定的数据库管理系统——支持 PostgreSQL、MySQL、SQLite。

\n\n

安装

\n\n

sqlc 不是一个库,而是一个命令行工具。可以通过以下几种方式安装:

\n\n
# 通过 go install 安装(推荐)\ngo install github.com/sqlc-dev/sqlc/cmd/sqlc@latest\n\n# 通过 Homebrew 安装(macOS/Linux)\nbrew install sqlc\n\n# 从 GitHub 下载二进制文件\n# https://github.com/sqlc-dev/sqlc/releases
\n\n

安装后检查版本:

\n\n
sqlc version
\n\n

快速开始

\n\n

让我们创建一个演示 sqlc 工作的最小项目。

\n\n

1. 项目结构

\n\n
mkdir sqlc-demo && cd sqlc-demo\ngo mod init sqlc-demo
\n\n

2. sqlc 配置

\n\n

在项目根目录创建 sqlc.yaml 文件:

\n\n
version: "2"\nsql:\n  - engine: "postgresql"\n    queries: "queries.sql"\n    schema: "schema.sql"\n    gen:\n      go:\n        package: "db"\n        out: "db"\n        sql_package: "pgx/v5"
\n\n

3. 数据库模式

\n\n

schema.sql 文件:

\n\n
CREATE TABLE authors (\n    id   BIGSERIAL PRIMARY KEY,\n    name text NOT NULL,\n    bio  text\n);
\n\n

4. SQL 查询

\n\n

queries.sql 文件:

\n\n
-- name: GetAuthor :one\nSELECT * FROM authors\nWHERE id = $1;\n\n-- name: ListAuthors :many\nSELECT * FROM authors\nORDER BY name;\n\n-- name: CreateAuthor :one\nINSERT INTO authors (name, bio)\nVALUES ($1, $2)\nRETURNING *;\n\n-- name: DeleteAuthor :exec\nDELETE FROM authors\nWHERE id = $1;
\n\n

5. 生成代码

\n\n
sqlc generate
\n\n

执行后,db/ 文件夹中会出现生成的代码文件。现在可以在代码中使用它们:

\n\n
package main\n\nimport (\n    "context"\n    "fmt"\n    "log"\n\n    "github.com/jackc/pgx/v5/pgxpool"\n    "sqlc-demo/db"\n)\n\nfunc main() {\n    ctx := context.Background()\n    pool, err := pgxpool.New(ctx, "postgres://user:pass@localhost:5432/testdb")\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer pool.Close()\n\n    queries := db.New(pool)\n\n    // 创建作者\n    author, err := queries.CreateAuthor(ctx, db.CreateAuthorParams{\n        Name: "Brian Kernighan",\n        Bio:  "Co-author of The C Programming Language",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Printf("Created author: %+v\\n", author)\n\n    // 根据 ID 获取作者\n    fetched, err :=                    

推荐