上一节,咱们曾经定义和创立了咱们须要的目录,和我的项目初始化。这一节咱们就能够开始编写博客配置性能了。
下面咱们提到,咱们的配置处理函数将寄存在config目录中。咱们的我的项目还须要配置文件。配置文件咱们就命名为config.json。它是一个json文件,外面将蕴含了博客网站的根本信息、数据库配置信息等。
【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元
config.json 配置文件
为了不便查看和读取config.json,咱们将它放在我的项目的config目录下。它外面将蕴含的字段信息有:
{
"mysql": {
"database": "irisweb",
"user": "root",
"password": "123456",
"host": "localhost",
"port": 3306
},
"server": {
"site_name": "irisweb 博客",
"env": "development",
"port": 8001,
"log_level": "debug"
}
}
字段阐明:
mysql 字段蕴含了连贯mysql数据库的信息。database 为数据库名称;user 为数据库用户名;password 为数据库明码;host 为数据库域名或ip地址;port 为数据库端口。
server 字段蕴含了博客网站的根本信息。site_name 为网站名称,网站页面会调用到;env 为博客网站的开发环境,值为development时,示意开发中,将会输入一些开发信息供参考,值为production示意部署在生产环境中,程序将不输入debug信息;port 为博客网站golang运行的端口,通过这个端口能够拜访到网站页面;log_level 示意日志的记录级别,值为debug的时候,示意记录debug级别的信息。
读取json文件
下面的配置文件config.json定义好并放到config目录后,咱们还须要编写代码,让golang能够读取它,能力在我的项目中调用配置文件中的信息。这些文件咱们都搁置在config文件夹中。
为了不便程序读取,咱们先给下面两个字段创立两个承载这些具体字段的构造体:
mysql.go
package config
type mysqlConfig struct {
Database string `json:"database"`
User string `json:"user"`
Password string `json:"password"`
Host string `json:"host"`
Port int `json:"port"`
Url string `json:"-"`
}
它对应的是方才咱们定义的json文件中的mysql字段。
构造体的定义是应用关键字 type 和 struct 来申明一个构造体,以关键字 type 开始,之后是新类型的名字,最初是关键字 struct。
构造体里的字段都有名字,比方下面例子中的 Database 和 User 等等。如果一个字段在代码中从来不会被用到,那能够把它命名为 _,即空标识符。
构造体变量采纳大写能够从内部拜访到,两头的string、int为这个字段的字段类型,“蕴含的内容为构造体字段指定一个标记信息,下面的标记示意是json字段的对应字段名称。
构造体中的字段能够是任何类型,甚至是构造体自身,也能够是函数或者接口。能够申明构造体类型的一个变量。
同一个包中,不能呈现同名的构造体,不同包不受限制。
server.go
package config
type serverConfig struct {
SiteName string `json:"site_name"`
Env string `json:"env"`
Port int `json:"port"`
LogLevel string `json:"log_level"`
}
server.go对应的的是json文件的server字段。
config.go
package config
type configData struct {
DB mysqlConfig `json:"mysql"`
Server serverConfig `json:"server"`
}
这个示意config.json的整体构造。
用构造体解析json
解析json须要一些函数来反对,咱们将这些函数都写在config.go 外面。
定义变量
var ExecPath string
var JsonData configData
var ServerConfig serverConfig
var DB *gorm.DB
定义的这四个变量,将是前面咱们博客我的项目中须要应用的变量。
定义执行目录
func initPath() {
sep := string(os.PathSeparator)
//root := filepath.Dir(os.Args[0])
//ExecPath, _ = filepath.Abs(root
ExecPath, _ = os.Getwd()
length := utf8.RuneCountInString(ExecPath)
lastChar := ExecPath[length-1:]
if lastChar != sep {
ExecPath = ExecPath + sep
}
}
下面次要是获取运行环境的目录,来确定我的项目目录,它有2种解决办法,一种是应用执行文件所在的目录,另一种是应用执行命令时所在的目录。
执行文件所在目录的获取形式是:
root := filepath.Dir(os.Args[0])
ExecPath, _ := filepath.Abs(root)
执行命令时所在目录的获取形式是:
ExecPath, _ := os.Getwd()
他们的利用场景有所不同,依据理论抉择应用。
为了开发中测试不便,本我的项目临时应用执行时目录。
读取json文件
func InitJSON() {
rawConfig, err := ioutil.ReadFile("./config.json")
if err != nil {
//未初始化
fmt.Println("Invalid Config: ", err.Error())
os.Exit(-1)
}
if err := json.Unmarshal(rawConfig, &JsonData); err != nil {
fmt.Println("Invalid Config: ", err.Error())
os.Exit(-1)
}
}
读取json函数,咱们应用ioutil包来将json文件读取到字节变量中。这里减少了判断,如果文件不存在,则返回谬误。接着将内容解析到构造体中,如果是一个规范的json字符串,则这里能够解析胜利,如果不胜利,则要查看config.json 是否配置正确了。
解析server
func initServer() {
ServerConfig = JsonData.Server
}
将server的字段赋值给ServerConfig变量
解析mysql
func InitDB(setting *mysqlConfig) error {
var db *gorm.DB
var err error
url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
setting.User, setting.Password, setting.Host, setting.Port, setting.Database)
setting.Url = url
db, err = gorm.Open(mysql.Open(url), &gorm.Config{})
if err != nil {
return err
}
sqlDB, err := db.DB()
if err != nil {
return err
}
sqlDB.SetMaxIdleConns(1000)
sqlDB.SetMaxOpenConns(100000)
sqlDB.SetConnMaxLifetime(-1)
DB = db
return nil
}
咱们在解析mysql的时候,先组装好mysql包连贯所用的连贯字符串,而后通过连贯字符串,应用mysql包来关上链接,再将mysql连贯交给gorm来治理,这样子,最终咱们就能够应用gorm的orm性能了。
在连贯完了之后,咱们还须要做一些检测,比方,是否连贯胜利。
连贯胜利后,尝试抉择获取到连贯对象,给连贯对象设置闲暇时的最大连接数、设置与数据库的最大关上连接数,每一个连贯的生命周期等信息。
在开始的时候执行
func init() {
initPath()
//读取json
initJSON()
//读取server
initServer()
//初始化数据库
err := InitDB(&JsonData.DB)
if err != nil {
fmt.Println("Failed To Connect Database: ", err.Error())
os.Exit(-1)
}
}
golang中的init函数是golang的一个非凡函数,它优先于golang的main函数执行,实现包级别的一些初始化操作。
所以,咱们能够在这里初始化我的项目的根本信息,让后续程序跑起来的时候能够失去设置好的配置信息。
残缺的config.go
下面分步解释了配置文件和配置文件的各个函数,这里将它组合起来成一个残缺的文件。
package config
import (
"encoding/json"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"io/ioutil"
"os"
"unicode/utf8"
)
type configData struct {
DB mysqlConfig `json:"mysql"`
Server serverConfig `json:"server"`
}
func initPath() {
sep := string(os.PathSeparator)
//root := filepath.Dir(os.Args[0])
//ExecPath, _ = filepath.Abs(root
ExecPath, _ = os.Getwd()
length := utf8.RuneCountInString(ExecPath)
lastChar := ExecPath[length-1:]
if lastChar != sep {
ExecPath = ExecPath + sep
}
}
func initJSON() {
rawConfig, err := ioutil.ReadFile(fmt.Sprintf("%sconfig.json", ExecPath))
if err != nil {
//未初始化
fmt.Println("Invalid Config: ", err.Error())
os.Exit(-1)
}
if err := json.Unmarshal(rawConfig, &JsonData); err != nil {
fmt.Println("Invalid Config: ", err.Error())
os.Exit(-1)
}
}
func InitDB(setting *mysqlConfig) error {
var db *gorm.DB
var err error
url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
setting.User, setting.Password, setting.Host, setting.Port, setting.Database)
setting.Url = url
db, err = gorm.Open(mysql.Open(url), &gorm.Config{})
if err != nil {
return err
}
sqlDB, err := db.DB()
if err != nil {
return err
}
sqlDB.SetMaxIdleConns(1000)
sqlDB.SetMaxOpenConns(100000)
sqlDB.SetConnMaxLifetime(-1)
DB = db
return nil
}
func initServer() {
ServerConfig = JsonData.Server
}
var ExecPath string
var JsonData configData
var ServerConfig serverConfig
var DB *gorm.DB
func init() {
initPath()
//读取json
initJSON()
//读取server
initServer()
//初始化数据库
err := InitDB(&JsonData.DB)
if err != nil {
fmt.Println("Failed To Connect Database: ", err.Error())
os.Exit(-1)
}
}
测试后果
config写完了,咱们还须要测试一下。
在根目录执行go mod命令来将包下载下来
go mod tidy
go mod vendor
残缺的我的项目示例代码托管在GitHub上,须要查看残缺的我的项目代码能够到github.com/fesiong/goblog 上查看,也能够间接fork一份来在下面做批改。