在 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