在 Go 中鏈接數據庫的方式有不少, 這裏咱們選擇使用 ORM 的方式, 也就不用寫原生的 SQL 語句了.mysql
Go 的 ORM 庫也有不少, 這裏選擇了 gorm.git
go get -u github.com/jinzhu/gorm
複製代碼
數據庫選擇了最主流的 mysql.github
建立數據庫的方式有不少, 爲了便於清理, 選擇使用 docker 建立數據庫.web
新建一個 docker-compose.yml
文件, 在根目錄下:sql
version: "3.7"
services:
mysql:
image: mysql:8
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: 1234
ports:
- 3306:3306
adminer:
image: adminer:4
ports:
- 8080:8080
dbclient:
image: mysql:8
command: mysql -hmysql -uroot -p
# source /home/script/db.sql
# select * from tb_users \G;
volumes:
- ./script:/home/script
複製代碼
運行下面的命令在後臺啓動數據庫:docker
docker-compose up -d mysql
複製代碼
使用下面的命令鏈接到 msyql 的 cli 上:數據庫
docker-compose run --rm dbclient
複製代碼
這會提示你輸入密碼, 密碼是 1234 (在 mysql 的環境變量 MYSQL_ROOT_PASSWORD 中設置).api
而後, 在 cli 中輸入如下 SQL, 建立一個表格:bash
CREATE DATABASE IF NOT EXISTS `db_apiserver`;
複製代碼
接下來, 就能夠完善 Go 代碼了.服務器
在根目錄下建立一個 model 文件夾, 這裏定義數據模型, 以及數據庫的初始鏈接.
在 model 目錄下建立一個 init.go 文件, 用於初始化數據庫鏈接.
package model
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
type Database struct {
Self *gorm.DB
}
// 單例
var DB *Database
func (db *Database) Init() {
DB = &Database{
Self: GetDB(),
}
}
func (db *Database) Close() {
DB.Self.Close()
}
func openDB(username, password, addr, name string) *gorm.DB {
config := fmt.Sprintf(
"%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=%t&loc=%s",
username,
password,
addr,
name,
true,
// "Asia%2FShanghai", // 必須是 url.QueryEscape 的
"Local",
)
db, err := gorm.Open("mysql", config)
if err != nil {
logrus.Fatalf("數據庫鏈接失敗. 數據庫名字: %s. 錯誤信息: %s", name, err)
} else {
logrus.Infof("數據庫鏈接成功, 數據庫名字: %s", name)
}
setupDB(db)
return db
}
func setupDB(db *gorm.DB) {
db.LogMode(viper.GetBool("gormlog"))
// 用於設置最大打開的鏈接數,默認值爲0表示不限制.設置最大的鏈接數,能夠避免併發過高致使鏈接mysql出現too many connections的錯誤。
//db.DB().SetMaxOpenConns(20000)
// 用於設置閒置的鏈接數.設置閒置的鏈接數則當開啓的一個鏈接使用完成後能夠放在池裏等候下一次使用。
db.DB().SetMaxIdleConns(0)
}
func InitDB() *gorm.DB {
return openDB(
viper.GetString("db.username"),
viper.GetString("db.password"),
viper.GetString("db.addr"),
viper.GetString("db.name"),
)
}
func GetDB() *gorm.DB {
return InitDB()
}
複製代碼
注意導入的時候, 須要導入對應的數據庫驅動, mysql 須要以下的導入:
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
複製代碼
主要是定義了一個結構來保存數據庫實例 *gorm.DB
, 用到了單例模式:
type Database struct {
Self *gorm.DB
}
// 單例
var DB *Database
複製代碼
而後定義了數據庫的初始化方法和關閉方法.
打開的時候用到了配置文件中的參數, 須要在配置文件 config.yaml 中添加以下的參數:
db:
name: db_apiserver
addr: 127.0.0.1:3306
username: root
password: "1234"
複製代碼
在 runServer 函數中添加下面的代碼:
// 初始化數據庫
model.DB.Init()
defer model.DB.Close()
複製代碼
其實鏈接數據庫的問題並不太大, 之前以爲麻煩是由於在本地啓動一個數據庫麻煩, 可是在有了 docker 以後, 一切就變得簡單可重複了, 不再用擔憂兼容性了.
做爲版本 v0.4.0