介绍
上一篇我们用GraphQL 已经有个基本的认识
接着来模拟真实的情境搭配Database 来使用
这篇主要都是在初始化环境
示例代码
通过 Docker 设置 MySQL 数据库
从 DockerHub 拉取 MySQL 镜像docker pull mysql
创建MySQL数据库
$ docker exec -it mysql bash
$ mysql -u root -p
$ CREATE DATABASE hackernews;
模型和迁移
接着我们需要利用GitHub - golang-migrate/migrate: Database migrations. CLI and Golang library.这个Package 来处理Migrations
依照下列结构创建资料夹
go-graphql-hackernews
--internal
----pkg
------db
--------migrations
----------mysql
最后所有步骤完成后的资料夹分布
依照指令初始化 migrate package
中间遇到缺少的dependency 就看console 指示用 go get
抓下来
$ go get -u github.com/go-sql-driver/mysql
$ go build -tags 'mysql' -ldflags="-X main.Version=1.0.0" -o $GOPATH/bin/migrate
$ github.com/golang-migrate/migrate/v4/cmd/migrate/
$ cd internal/pkg/db/migrations/
$ migrate create -ext sql -dir mysql -seq create_users_table
$ migrate create -ext sql -dir mysql -seq create_links_table
接着会看到几个创建好的.sql
在 000001_create_users_table.up.sql
内新增
CREATE TABLE IF NOT EXISTS Users(
ID INT NOT NULL UNIQUE AUTO_INCREMENT,
Username VARCHAR (127) NOT NULL UNIQUE,
Password VARCHAR (127) NOT NULL,
PRIMARY KEY (ID)
)
在 000002_create_links_table.up.sql
内新增
CREATE TABLE IF NOT EXISTS Links(
ID INT NOT NULL UNIQUE AUTO_INCREMENT,
Title VARCHAR (255) ,
Address VARCHAR (255) ,
UserID INT ,
FOREIGN KEY (UserID) REFERENCES Users(ID) ,
PRIMARY KEY (ID)
)
cd
回到根目录执行
$ migrate -database mysql://root:dbpass@/hackernews -path internal/pkg/db/migrations/mysql up
在 internal/pkg/db/mysql
新增 mysql.go
package database
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/golang-migrate/migrate"
"github.com/golang-migrate/migrate/database/mysql"
_ "github.com/golang-migrate/migrate/source/file"
"log"
)
var Db *sql.DB
func InitDB() {
// Use root:dbpass@tcp(172.17.0.2)/hackernews, if you're using Windows.
db, err := sql.Open("mysql", "root:dbpass@tcp(localhost)/hackernews")
if err != nil {
log.Panic(err)
}
if err = db.Ping(); err != nil {
log.Panic(err)
}
Db = db
}
func CloseDB() error {
return Db.Close()
}
func Migrate() {
if err := Db.Ping(); err != nil {
log.Fatal(err)
}
driver, _ := mysql.WithInstance(Db, &mysql.Config{})
m, _ := migrate.NewWithDatabaseInstance(
"file://internal/pkg/db/migrations/mysql",
"mysql",
driver,
)
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
log.Fatal(err)
}
}
改写server.go
这段我有改写一些,教学的sample直接拿来用会报错,改了几个地方
mysql.go
程式码的package
改名为mig
,不然会抓不到importgo get -u github.com/go-chi/chi/v5
抓取需要初始化 HTTP router 的 packagehackernews.XXX()
前缀打错了,改成graph
- .XXX()
func main() {
port := os.Getenv("PORT")
if port == "" {
port = defaultPort
}
router := chi.NewRouter()
mig.InitDB()
defer mig.CloseDB()
mig.Migrate()
server := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}}))
router.Handle("/", playground.Handler("GraphQL playground", "/query"))
router.Handle("/query", server)
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":"+port, router))
}