简介
在 Go 语言中编写数据库操作代码真的非常痛苦!database/sql
标准库提供的都是比较底层的接口。我们需要编写大量重复的代码。大量的模板代码不仅写起来烦,而且还容易出错。有时候字段类型修改了一下,可能就需要改动很多地方;添加了一个新字段,之前使用select *
查询语句的地方都要修改。如果有些地方有遗漏,可能就会造成运行时panic
。即使使用 ORM 库,这些问题也不能完全解决!这时候,sqlc
来了!sqlc
可以根据我们编写的 SQL 语句生成类型安全的、地道的 Go 接口代码,我们要做的只是调用这些方法。
快速使用
先安装:
$ go get github.com/kyleconroy/sqlc/cmd/sqlc
当然还有对应的数据库驱动:
$ go get github.com/lib/pq
$ go get github.com/go-sql-driver/mysql
sqlc
是一个命令行工具,上面代码会将可执行程序sqlc
放到$GOPATH/bin
目录下。我习惯把$GOPATH/bin
目录加入到系统PATH
中。所以可以执行使用这个命令。
因为sqlc
用到了一个 linux 下的库,在 windows 上无法正常编译。在 windows 上我们可以使用 docker 镜像kjconroy/sqlc
。docker 的安装就不介绍了,网上有很多教程。拉取kjconroy/sqlc
镜像:
$ docker pull kjconroy/sqlc
然后,编写 SQL 语句。在schema.sql
文件中编写建表语句:
CREATE TABLE authors (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
bio TEXT
);
在query.sql
文件中编写查询语句:
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;
-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;
-- name: CreateAuthor :exec
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
)
RETURNING *;
-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1;
sqlc
支持 PostgreSQL 和 MySQL,不过对 MySQL 的支持是实验性的。期待后续完善对 MySQL 的支持,增加对其它数据库的支持。本文我们使用的是 PostgreSQL。编写数据库程序时,上面两个 sql 文件是少不了的。sqlc
额外只需要一个小小的配置文件sqlc.yaml
:
version: "1"
packages:
- name: "db"
path: "./db"
queries: "./query.sql"
schema: "./schema.sql"
-
version
:版本; -
packages
:-
name
:生成的包名; -
path
:生成文件的路径; -
queries
:查询 SQL 文件; -
schema
:建表 SQL 文件。
-
在 windows 上执行下面的命令生成对应的 Go 代码:
docker run --rm -v CONFIG_PATH:/src -w /src kjconroy/sqlc generate
上面的CONFIG_PATH
替换成配置所在目录,我的是D:\code\golang\src\github.com\darjun\go-daily-lib\sqlc\get-started
。sqlc
为我们在同级目录下生成了数据库操作代码,目录结构如下:
db
├── db.go
├── models.go
└── query.sql.go
sqlc
根据我们schema.sql
和query.sql
生成了模型对象结构:
// models.go
type Author struct {
ID int64
Name string
Bio sql.NullString
}
和操作接口:
// query.sql.go
func (q *Queries) CreateAuthor(ctx context.Context, arg CreateAuthorParams) (Author, error)
func (q *Queries) DeleteAuthor(ctx context.Context, id int64) error
func (q *Queries) GetAuthor(ctx context.Context, id int64) (Author, error)
func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error)
其中Queries
是sqlc
封装