golang从SQL生成类型安全代码的插件库sqlc的使用
golang从SQL生成类型安全代码的插件库sqlc的使用
sqlc是一个从SQL生成类型安全代码的工具。它的工作原理如下:
- 你用SQL编写查询
- 运行sqlc生成这些查询的类型安全接口代码
- 编写调用生成代码的应用程序代码
基本使用示例
下面是一个完整的sqlc使用示例:
- 首先创建SQL文件
query.sql
:
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = ? LIMIT 1;
-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;
-- name: CreateAuthor :exec
INSERT INTO authors (
name, bio
) VALUES (
?, ?
);
-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = ?;
- 创建sqlc配置文件
sqlc.yaml
:
version: "2"
sql:
- engine: "mysql"
schema: "schema.sql"
queries: "query.sql"
gen:
go:
package: "db"
out: "db"
- 运行sqlc生成代码:
sqlc generate
- 生成的Go代码可以直接在应用中使用:
package main
import (
"context"
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
"your-project/db"
)
func main() {
// 初始化数据库连接
dbConn, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
log.Fatal(err)
}
defer dbConn.Close()
// 创建查询实例
queries := db.New(dbConn)
// 使用生成的查询方法
ctx := context.Background()
// 创建作者
err = queries.CreateAuthor(ctx, db.CreateAuthorParams{
Name: "John Doe",
Bio: sql.NullString{String: "Author of many books", Valid: true},
})
if err != nil {
log.Fatal(err)
}
// 获取作者列表
authors, err := queries.ListAuthors(ctx)
if err != nil {
log.Fatal(err)
}
for _, author := range authors {
fmt.Printf("ID: %d, Name: %s\n", author.ID, author.Name)
}
}
主要特点
- 从SQL直接生成类型安全的Go代码
- 支持多种数据库引擎(MySQL, PostgreSQL等)
- 生成的代码完全类型安全,编译时检查SQL错误
- 支持查询参数绑定和结果映射
- 生成的代码干净简洁,易于使用
支持的查询类型
sqlc支持以下几种查询类型:
:one
- 返回单行结果:many
- 返回多行结果:exec
- 执行但不返回结果:execrows
- 执行并返回影响的行数
安装
可以通过以下方式安装sqlc:
# 使用Homebrew(MacOS)
brew install sqlc
# 使用Go
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
# 使用Docker
docker pull sqlc/sqlc
sqlc是一个强大的工具,可以显著提高使用SQL时的开发效率和类型安全性,特别适合在Go项目中使用。
更多关于golang从SQL生成类型安全代码的插件库sqlc的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang从SQL生成类型安全代码的插件库sqlc的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用sqlc生成类型安全的Go代码
sqlc是一个强大的工具,可以从SQL查询生成类型安全的Go代码。它通过分析你的SQL模式(schema)和查询,自动生成对应的Go结构体和函数,避免了手动编写大量样板代码。
安装sqlc
首先需要安装sqlc:
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
或者使用Homebrew (macOS):
brew install sqlc
基本使用
1. 创建配置文件
在项目根目录创建sqlc.yaml
配置文件:
version: "2"
sql:
- engine: "postgresql" # 也可以是mysql或sqlite
queries: "query/" # SQL查询文件目录
schema: "schema/" # SQL模式文件目录
gen:
go:
package: "db"
out: "db"
sql_package: "pgx/v5"
emit_json_tags: true
emit_prepared_queries: true
2. 创建SQL模式文件
在schema/
目录下创建schema.sql
:
CREATE TABLE authors (
id BIGSERIAL PRIMARY KEY,
name text NOT NULL,
bio text
);
CREATE TABLE books (
id BIGSERIAL PRIMARY KEY,
author_id BIGINT NOT NULL REFERENCES authors(id),
title text NOT NULL,
published date NOT NULL
);
3. 创建查询文件
在query/
目录下创建author.sql
:
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;
-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;
-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
)
RETURNING *;
-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1;
4. 生成代码
运行命令生成代码:
sqlc generate
这将在db/
目录下生成Go代码。
生成的代码结构
sqlc会生成以下文件:
db.go
- 数据库连接和查询器结构体models.go
- 数据库表对应的Go结构体query/
- 每个SQL查询文件对应的Go代码
使用生成的代码
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/jackc/pgx/v5"
"your-project/db"
)
func main() {
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer conn.Close(context.Background())
queries := db.New(conn)
// 创建作者
author, err := queries.CreateAuthor(context.Background(), db.CreateAuthorParams{
Name: "J.R.R. Tolkien",
Bio: "Author of The Lord of the Rings",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created author: %v\n", author)
// 获取作者
fetchedAuthor, err := queries.GetAuthor(context.Background(), author.ID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Fetched author: %v\n", fetchedAuthor)
// 列出所有作者
authors, err := queries.ListAuthors(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println("All authors:")
for _, a := range authors {
fmt.Printf("- %s\n", a.Name)
}
}
高级特性
1. 自定义类型
可以在配置文件中指定类型映射:
overrides:
- db_type: "uuid"
go_type: "github.com/google/uuid.UUID"
- db_type: "text"
go_type: "github.com/lib/pq.StringArray"
go_struct_tag: "json:\"-\""
2. 参数和结果结构体
sqlc会为每个查询生成参数和结果结构体。例如对于GetAuthor
查询,会生成:
type GetAuthorParams struct {
ID int64
}
type GetAuthorRow struct {
ID int64
Name string
Bio sql.NullString
}
3. 事务支持
生成的代码天然支持事务:
tx, err := conn.Begin(context.Background())
if err != nil {
log.Fatal(err)
}
defer tx.Rollback(context.Background())
qtx := queries.WithTx(tx)
// 使用qtx执行事务操作
最佳实践
- 将SQL查询组织到逻辑文件中
- 使用注释为查询添加文档
- 考虑将生成的代码提交到版本控制
- 在CI/CD流程中加入sqlc生成步骤
- 为复杂查询编写测试
sqlc通过将SQL直接转换为类型安全的Go代码,大大减少了数据库交互的样板代码,同时保持了SQL的灵活性和可读性。