go-sqlc-typed-queries

test12026-10-2615 次阅读

传统写法的痛点

用 database/sql 手写查询,结果要一行行 rows.Scan 到变量,列名拼错、类型对不上只能在运行期爆。sqlc 反其道而行:你写普通的 SQL,它在编译期生成类型安全的 Go 代码,字段、参数、返回行全部有类型,改了表结构重新生成就能发现调用方哪里没跟上。

定义 schema 与查询

schema.sql 描述表结构,queries.sql 写业务 SQL,每条查询用注释起一个名字,并标注返回一行还是多行。

-- schema.sql
CREATE TABLE authors (
  id   BIGSERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  bio  TEXT NOT NULL
);

CREATE TABLE books (
  id          BIGSERIAL PRIMARY KEY,
  author_id   BIGINT NOT NULL REFERENCES authors(id),
  title       TEXT NOT NULL,
  price_cents BIGINT NOT NULL
);
-- queries.sql
-- name: GetAuthor :one
SELECT id, name, bio FROM authors WHERE id = $1;

-- name: ListBooksByAuthor :many
SELECT id, author_id, title, price_cents
FROM books
WHERE author_id = $1
ORDER BY title;

-- name: CreateBook :one
INSERT INTO books (author_id, title, price_cents)
VALUES ($1, $2, $3)
RETURNING id, author_id, title, price_cents;

配置 sqlc.yaml

指定引擎、schema、queries 与输出目录,sql_package 选 pgx/v5 可以直连连接池。

version: "2"
sql:
  - engine: "postgresql"
    queries: "queries.sql"
    schema: "schema.sql"
    gen:
      go:
        package: "db"
        out: "internal/db"
        sql_package: "pgx/v5"
        emit_json_tags: true

生成后怎么用

运行 sqlc generate,它会产出 Book、Author 结构体以及带参数的查询方法。调用方拿到的全是强类型,价格这类字段也不会被误当成浮点。

package main

import (
	"context"
	"log"

	"github.com/jackc/pgx/v5/pgxpool"
	"example.com/app/internal/db"
)

func main() {
	ctx := context.Background()
	pool, _ := pgxpool.New(ctx, "postgres://user:pass@localhost:5432/books")
	queries := db.New(pool)

	book, err := queries.CreateBook(ctx, db.CreateBookParams{
		AuthorID:    1,
		Title:       "The Pragmatic Programmer",
		PriceCents:  3999,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println(book.ID, book.Title, book.PriceCents)

	books, _ := queries.ListBooksByAuthor(ctx, 1)
	log.Println(len(books))
}

收益与注意点

  • 字段类型由数据库方言推断,避免 Scan 到错类型在运行期才炸。
  • SQL 仍是手写,索引、连表优化完全掌控,不丢灵活性。
  • nullable 列会生成 pgtype 类型,需要额外处理,建表时能用 NOT NULL 就别留空。
  • CI 里加一步 sqlc diff 或 sqlc vet,SQL 和生成代码不一致就直接红。
T

test1

文章作者

传统写法的痛点 用 database/sql 手写查询,结果要一行行 rows.Scan 到变量,列名拼错、类型对不上...

分类
技术
发布时间
2026-10-26
字数
约 1962 字
阅读
15 次