一文讲懂Go语言如何使用配置文件连接数据库
- viper
-
- [1. viper简介](#1. viper简介)
- [2. viper 读取.toml配置文件](#2. viper 读取.toml配置文件)
- 连接数据库
-
- [1. 定义数据库对象](#1. 定义数据库对象)
- [2. 定义初始化函数](#2. 定义初始化函数)
- [3. 定义 get 函数](#3. 定义 get 函数)
- [4. 定义 main 函数, 连接数据库](#4. 定义 main 函数, 连接数据库)
配置文件在软件开发和系统管理中扮演着重要的角色,它们用于定义软件运行时的各种参数和设置。其保证了项目代码的灵活性, 安全性, 维护性等多重性质。
本文以 viper
第三方库连接 MySQL
为例, 讲解 go语言
如何使用配置文件连接数据库。
本文默认读者已经熟悉如何直接从 go语言 连接数据库。若需了解如何从go语言连接数据库可以点击 go语言连接MySQL数据库详解(单机版) 进行学习
viper
1. viper简介
Viper支持JSON, TOML, YAML, HCL, INI, envfile和Java Properties files文件
。viper可以搜索多条路径,但是 目前,单个Viper实例只支持单个配置文件。
2. viper 读取.toml配置文件
TOML文件格式是一种旨在易于阅读且具有最小语义的配置文件格式。它由GitHub上的开发者Tom Preston-Werner创建,旨在成为一种更简单、更明确的替代JSON和YAML等其他配置文件格式的选择。其拥有易读性, 简介性, 明确性等优点。
.toml配置文件教程
下载 viper
bash
go get github.com/spf13/viper
定义Go语言结构体
go
# 因实际开发中不止需要配置数据库, 故使用嵌套结构体
type config struct {
Database Database
}
type Database struct {
MySQL MySQLConf
}
type MySQLConf struct {
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
DBName string `mapstructure:"db_name"`
MaxOpenConns int `mapstructure:"max_open_conns"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
Timeout string `mapstructure:"timeout"`
}
编写与Go语言结构体对应的.toml配置文件
bash
[databasse]
[database.mysql]
user = "Golang"
password = "go123123"
host = "localhost"
port = 3306
db_name= "test"
max_open_conns = 100
max_idle_conns = 20
timeout = "15s"
定义初始化函数
go
# 定义结构体对象
var c config
func init() {
# 设置配置文件的文件名
viper.SetConfigName("config")
# 设置配置文件的文件格式
viper.SetConfigType("toml")
# 设置配置文件的文件路径
viper.AddConfigPath(".")
# 日志文件对象
logFile, err := os.OpenFile("/var/lib/APP/conf.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
}
defer logFile.Close()
log.SetOutput(logFile)
// 读取配置文件
err = viper.ReadInConfig()
if err != nil {
log.Printf("config load Error: %v \n", err)
} else {
log.Println("configuration file was read successfully")
}
// 将 viper 读到的反数据序列化写入 config 对象中
viper.Unmarshal(&c)
}
定义get函数
go
func GetConfig() *config {
return &c
}
连接数据库
1. 定义数据库对象
go
var _db *sqlx.DB
2. 定义初始化函数
go
func init() {
c := config.GetConfig()
dbUser := c.Database.MySQL.User
dbPass := c.Database.MySQL.Password
dbHost := c.Database.MySQL.Host
dbPort := c.Database.MySQL.Port
dbName := c.Database.MySQL.DBName
timeout := c.Database.MySQL.Timeout
logFile, err := os.OpenFile("/var/lib/APP/mysql.log",os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
}
defer logFile.Close()
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&timeout=%s", dbUser, dbPass, dbHost, dbPort, dbName, timeout)
_db, err := sqlx.Connect("mysql", dsn)
if err != nil {
log.Printf("MySQL connect err: %v", err)
}
log.SetOutput(logFile)
_db.SetMaxOpenConns(c.Database.MySQL.MaxOpenConns)
_db.SetMaxIdleConns(c.Database.MySQL.MaxIdleConns)
}
3. 定义 get 函数
go
func GetDB() *sqlx.DB {
return _db
}
4. 定义 main 函数, 连接数据库
go
func main() {
mysql := mysql.GetDB()
defer mysql.Close()
sqlStr := "insert into sql_test.user(name, age) values (?, ?)"
stmt, err := db.Prepare(sqlStr)
if err != nil {
fmt.Printf("prepare failed err: %v \n", err)
}
_, err = stmt.Exec("张三", 24)
if err != nil {
fmt.Printf("insert failed err: %v \n", err)
}
fmt.Println("insert success")
}