使用 Go 链接数据库

简介

在 Go 中链接数据库的方式有不少, 这里咱们选择使用 ORM 的方式, 也就不用写原生的 SQL 语句了.mysql

Go 的 ORM 库也有不少, 这里选择了 gorm.git

安装 gorm

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

相关文章
相关标签/搜索