简介
sqlc 可以生成从 SQL 生成类型安全代码。它的工作原理是:
- 使用 SQL 书写查询语句。
- 运行 sqlc 生成 Go 代码,该代码为这些查询提供类型安全的接口。
- 在应用程序代码中调用生成的代码与数据库进行交互。
安装
sqlc 有多种安装方式:
macOS:
brew install sqlc
Ubuntu:
sudo snap install sqlc
go安装:
# Go >= 1.17:
go install github.com/kyleconroy/sqlc/cmd/sqlc@latest
# Go < 1.17:
go get github.com/kyleconroy/sqlc/cmd/sqlc
docker安装:
docker pull kjconroy/sqlc
其它:
https://github.com/kyleconroy/sqlc/releases
入门使用
插件 sqlc.yaml
首先创建 sqlc.yaml 文件, sqlc 会在当前目录下查找 sqlc.yaml 或 sqlc.json文件。
# sqlc.yaml
version: 1
packages:
- path: "tutorial"
name: "tutorial"
engine: "mysql"
schema: "schema.sql"
queries: "query.sql"
创建sql文件
sqlc需要得知数据库表结构和相应的sql语句,我们创建schema.sql定义表结构:
CREATE TABLE games (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name text NOT NULL,
url text
);
创建 query.sql 包含需要的sql语句:
-- name: Getgame :one
SELECT * FROM games
WHERE id = ? LIMIT 1;
-- name: ListGames :many
SELECT * FROM games
ORDER BY name;
-- name: CreateGame :execresult
INSERT INTO games (
name, url
) VALUES (
?, ?
)
-- name: DeleteGame :exec
DELETE FROM games
WHERE id = ?;
-- name: UpdateGame :exec
UPDATE games
set name = ?,
url = ?
WHERE id = ?;
生成代码
接下来使用 sqlc generate
,在根目录下会生成一个tutorial目录,生成后项目目录如下:
.
├── go.mod
├── query.sql
├── schema.sql
├── sqlc.yaml
└── tutorial
├── db.go
├── models.go
└── query.sql.go
测试
接下来编写代码来使用生成的数据库代码:
---
title: "sqlc初体验"
date: 2023-05-20T15:54:29+08:00
draft: true
tags: [ "sqlc","database","sql" ]
---
## 简介
sqlc 可以生成从 SQL 生成类型安全代码。它的工作原理是:
* 使用 SQL 书写查询语句。
* 运行 sqlc 生成 Go 代码,该代码为这些查询提供类型安全的接口。
* 在应用程序代码中调用生成的代码与数据库进行交互。
## 安装
sqlc 有多种安装方式:
macOS:
`
brew install sqlc
`
Ubuntu:
`
sudo snap install sqlc
`
go安装:
```console
# Go >= 1.17:
go install github.com/kyleconroy/sqlc/cmd/sqlc@latest
# Go < 1.17:
go get github.com/kyleconroy/sqlc/cmd/sqlc
docker安装:
docker pull kjconroy/sqlc
其它:
https://github.com/kyleconroy/sqlc/releases
入门使用
插件 sqlc.yaml
首先创建 sqlc.yaml 文件, sqlc 会在当前目录下查找 sqlc.yaml 或 sqlc.json文件。
# sqlc.yaml
version: 1
packages:
- path: "tutorial"
name: "tutorial"
engine: "mysql"
schema: "schema.sql"
queries: "query.sql"
创建sql文件
sqlc需要得知数据库表结构和相应的sql语句,我们创建schema.sql定义表结构:
CREATE TABLE games (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name text NOT NULL,
url text
);
创建 query.sql 包含需要的sql语句:
-- name: Getgame :one
SELECT * FROM games
WHERE id = ? LIMIT 1;
-- name: ListGames :many
SELECT * FROM games
ORDER BY name;
-- name: CreateGame :execresult
INSERT INTO games (
name, url
) VALUES (
?, ?
)
-- name: DeleteGame :exec
DELETE FROM games
WHERE id = ?;
-- name: UpdateGame :exec
UPDATE games
set name = ?,
url = ?
WHERE id = ?;
生成代码
接下来使用 sqlc generate
,在根目录下会生成一个tutorial目录,生成后项目目录如下:
.
├── go.mod
├── query.sql
├── schema.sql
├── sqlc.yaml
└── tutorial
├── db.go
├── models.go
└── query.sql.go
测试
接下来编写代码来使用生成的数据库代码:
package main
import (
"context"
"database/sql"
"log"
"reflect"
"sqlc-demo/tutorial"
_ "github.com/go-sql-driver/mysql"
)
func run() error {
ctx := context.Background()
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
return err
}
queries := tutorial.New(db)
games, err := queries.ListGames(ctx)
if err != nil {
return err
}
log.Println(games)
result, err := queries.CreateGame(ctx, tutorial.CreateGameParams{
Name: "game1",
Url: sql.NullString{
String: "www.google.com",
Valid: true,
},
})
if err != nil {
return err
}
insertedGameID, err := result.LastInsertId()
if err != nil {
return err
}
log.Println(insertedGameID)
game, err := queries.GetGame(ctx, insertedGameID)
if err != nil {
return err
}
log.Println(reflect.DeepEqual(insertedGameID, game.ID))
return nil
}
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
总结
本文简单使用 sqlc 根据定义的sql语句来生成go代码,相比于ent等orm, sqlc 是根据定义的sql语句生成代码,如果数据库代码出现问题,更容易发现问题,也容易进行数据库审计。
参考
## 参考
* https://docs.sqlc.dev/en/stable/index.html