使用 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

相關文章
相關標籤/搜索