1. 什么是sqlc?
google sqlc doc可以看到sqlc官網對於自己的定位,其主要作用就是從SQL生成可直接調用的go接口
我們使用sqlc可以簡單分為以下三個步驟:
- 寫SQL
- run sqlc生成我們所需要的go查詢接口
- 使用這些接口與數據庫交互
sqlc doc:https://docs.sqlc.dev/en/stable/index.html
2. sqlc安裝
macos安裝
brew install sqlc
go install (go version>=1.17)
go install github.com/kyleconroy/sqlc/cmd/sqlc@latest
ubuntu
sudo snap install sqlc
docker(這種工具安裝在docker上啟動有些不方便)
docker pull kjconroy/sqlc
3. 從SQL到golang code
現在sqlc支持的數據庫包括了MySQL和PostgreSQL,用法基本是一樣的,下面我們就以postgres來看怎樣讓sqlc為我們生成sql查詢的go code
首先我們cd到項目文件主目錄,執行下面的指令生成sqlc.yaml文件,這個文件會配置一些sqlc的信息
sqlc init
在yaml文件中我們可以編寫一些sqlc的初始化配置信息:
version: "1"
packages:
- name: "db" # package name
path: "./db/sqlc" # 生成的go code路徑
queries: "./db/query/" # sql語句路徑
schema: "./db/migration/" # 數據庫架構
engine: "postgresql" # 什么數據庫
emit_json_tags: true
emit_prepared_queries: false
emit_interface: true #生成一個所有query的接口文檔
emit_exact_table_names: false
emit_empty_slices: true
當然在寫ymal文件之前,我們需要做好一些准備工作:
- 創建上面用到的所有文件目錄
- 創建數據庫架構文件
然后我們就可以在query目錄下編寫我們需要的SQL語句了,讓我們看看使用sqlc和我們自己寫正常的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;
我們可以看到這和我們自己寫sql並無不同,最大的區別就是每一句sql上面都會有一個注釋
name: 后面的是我們要生成的那個go查詢接口的方法名,再后后面的one、many、exec都有不同的含義:
- one:只有一個返回值
- many:多個返回值
- exec:沒有返回值
好了,我們現在知道query.sql的簡單編寫規則了,我們可以根據自己的需求去修改:
-- name: CreateEntry :one
INSERT INTO entries (
account_id,
amount
) VALUES (
$1, $2
) RETURNING *;
-- name: GetEntry :one
SELECT * FROM entries
WHERE id = $1 LIMIT 1;
-- name: ListEntries :many
SELECT * FROM entries
WHERE account_id = $1
ORDER BY id
LIMIT $2
OFFSET $3;
可以看到我需要三個接口:
- CreateEntry:向entries表中插入數據,傳入參數為account_id, amount,返回值是我們插入的這條數據
- GetEntry:獲取指定id的信息,傳入參數為id,返回值是我們需要的這一條信息
- ListEntries:獲取一個account_id下多條轉賬信息,傳入參數是account_id, limit, offest,返回值是多條符合要求的數據
現在讓我們生成需要go code
sqlc generate
現在可以在db/sqlc文件夾下查看生成的go code

其實除了我們需要的entry.sql.go,還會生成三個.go文件,可以簡單看一下里面都是些什么內容:
db.go:初始化了一個Queries結構,我們需要傳入一個自己的db連接對象

models.go:就是將我們每個表的字段都做了一次結構體的封裝

querier.go:定義一個接口,封裝所有的sql查詢接口
entry.sql.go:用go實現了我們剛才寫的那些sql語句,一些輸入和輸出結構都用了struct來定義

至此我們就完全可以用go來與數據庫實現交互了,sqlc的優勢也很明顯了,我們只需要寫sql,而不需要關心go如何與sql進行交互的
同時sqlc還支持了語法錯誤的判斷,而不存在我們在運行程序是因為sql出錯而panic的情況
