SQLC

SQLC 設定與使用參考。

YAML 設定

version: "2"
sql:
  - engine: "sqlite"
    queries: "db/query.sql"
    schema: "db/schema.sql"
    gen:
      go:
        # 基礎設定
        package: "sqlite"
        out: "db/sqlite"

        # 代碼生成選項
        emit_interface: true                     # 生成 Querier 介面
        emit_json_tags: true                     # 生成 JSON 標籤
        emit_prepared_queries: true              # 使用預處理語句
        emit_exact_table_names: false            # 表名是否保持原樣
        emit_empty_slices: true                  # 空結果返回空切片
        emit_exported_queries: true              # 導出 SQL 查詢
        emit_result_struct_pointers: false       # 結果是否為指針
        emit_params_struct_pointers: false       # 參數是否為指針

        # 枚舉相關
        emit_enum_valid_method: true             # 生成枚舉驗證方法
        emit_all_enum_values: true               # 生成所有枚舉值列表

        # 字段命名
        emit_pointers_for_null_types: true       # NULL 值使用指針

        # 註釋生成
        emit_file_header_comments: true          # 文件頭部註釋
        emit_doc_comments: true                  # 生成文檔註釋

        # 框架整合
        emit_db_tags: true                       # 生成 db 標籤

設定選項說明

emit_interface

生成 Querier interface,有助於依賴注入和測試。

type Querier interface {
    GetBook(ctx context.Context, id int64) (Book, error)
    ListBooks(ctx context.Context) ([]Book, error)
}

emit_json_tags

為 struct 加上 json tag,方便序列化/反序列化。

type Book struct {
    ID    int64  `json:"id"`
    Title string `json:"title"`
}

emit_prepared_queries

生成預處理語句,提升性能,防止 SQL 注入。

emit_exact_table_names

效果
false (推薦)type Book struct {}
truetype Books struct {}

emit_empty_slices

查詢無結果時返回空切片而非 nil。

// true: books = []Book{}
// false: books = nil
var books []Book

emit_exported_queries

將 SQL 查詢導出為常量,方便查看實際執行的 SQL。

const getBookSQL = `SELECT * FROM books WHERE id = $1`

emit_result_struct_pointers

效果
falsefunc GetBook() (Book, error)
truefunc GetBook() (*Book, error)

emit_params_struct_pointers

當設定為 true 時,生成的查詢方法會使用指針參數。

func (q *Queries) GetUserByID(ctx context.Context, arg *GetUserByIDParams) (*User, error)
func (q *Queries) CreateUser(ctx context.Context, arg *CreateUserParams) (*User, error)

emit_enum_valid_method

自動為枚舉類型生成 Valid() 方法。

func (e UserStatus) Valid() bool {
    switch e {
    case UserStatusActive, UserStatusInactive, UserStatusSuspended:
        return true
    }
    return false
}

emit_all_enum_values

生成包含所有可能枚舉值的切片。

var AllSubscriptionTier = []SubscriptionTier{
    SubscriptionTierFree,
    SubscriptionTierBasic,
    SubscriptionTierPremium,
    SubscriptionTierEnterprise,
}

Annotations

Annotation說明
:one返回單筆結果,常用於 WHERE 主鍵查詢
:many返回多筆結果,回傳切片類型
:exec執行修改操作,不返回結果
:execresult返回 sql.Result(LastInsertId, RowsAffected)
:execrows返回受影響的行數
:execlastid執行 INSERT,返回自增 ID
:batchexec批次執行 DML
:batchone批次查詢單筆
:batchmany批次查詢多筆

資料庫支援

AnnotationPostgreSQLSQLiteMySQL
:one
:many
:exec
:execresult
:execrows
:execlastid
:batchexec
:batchmany
:batchone
  • batch* 系列只支援 PostgreSQL + pgx/v4、pgx/v5 驅動
  • SQLite 的 :execresult、:execrows 功能受限於 SQLite 本身限制
  • 所有 annotation 產生的程式碼都會包含 context.Context 參數