我們可以使用 database/sql
與 github.com/go-sql-driver/mysql
go-sql-driver/mysql
會自動處理好 註冊 MySQLDriver 到 database/mysql
, 重連斷開的連接, pooling 等等
import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) func main() { dbSource := "username:password@tcp(url:port)/db" db, err := sql.Open("mysql", dbSource) if err != nil { log.Fatal(err.Error()) } ... }
我們將使用 golang-migrate
去實現 db 的 migration
golang-migrate
brew install golang-migrate
migrate create -ext sql -dir {{generated migration file location}} -seq {{migration name}}
我們可以在 Makefile 加上這段, 這樣我們需要新增新的 migration 時只需要簡單的 make new_migrate
後輸入 migration 的名字後即可
new_migrate: @read -p "Enter migration name: " name; \ migrate create -ext sql -dir pkg/db/migration -seq $$name
我們輸入 create_user
後可以發現多了 migrate down 和 up 的 file 用來定義兩者分別要進行的動作
.
└── pkg
└── db
└── migration
├── 000001_create_user.down.sql
└── 000001_create_user.up.sql
# 000001_create_user.down.sql DROP TABLE IF EXISTS users; # 000001_create_user.up.sql CREATE TABLE `users` ( `id` BIGINT AUTO_INCREMENT PRIMARY KEY, `username` varchar(255) NOT NULL, `email` varchar(255) UNIQUE NOT NULL, `password` varchar(255) UNIQUE NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX `users_index_on_email_password` ON `users` (`email`, `password`);
make migrateup/migratedown
就可以完成動作了migrateup: migrate -path pkg/db/migration/ -database {{mysql address}} -verbose up migratedown: migrate -path pkg/db/migration/ -database {{mysql address}} -verbose down 1
sqlc generates fully type-safe idiomatic Go code from SQL
sqlc 可以直接將 raw sql 轉換成 golang code. 可以生成 model struct, querier interface 等等
# for mac brew install sqlc # for ubuntu sudo snap install sqlc # go install (require Go 1.21+) go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
# 定義好是哪個版本的 sqlc configuration version: "2" sql: # 我們將使用 mysql - engine: "mysql" # 會讀取哪裡去生成 schema, sqlc 會忽略 .down sql 所以可以直接指向我們之前放 migration 的 dir schema: "./pkg/db/migration/" # 會讀取哪裡取得我們支援的 query queries: "./pkg/db/query/" gen: go: # package 名稱 package: "sqlc" # 生成的 code 的位置 out: "./pkg/db/sqlc" # addition 的 configuration 可依照需求修改 emit_json_tags: true emit_prepared_queries: false emit_interface: true emit_exact_table_names: false emit_empty_slices: true