上一节,咱们曾经定义和创立了咱们须要的目录,和我的项目初始化。这一节咱们就能够开始编写博客配置性能了。
下面咱们提到,咱们的配置处理函数将寄存在config
目录中。咱们的我的项目还须要配置文件。配置文件咱们就命名为config.json
。它是一个json文件,外面将蕴含了博客网站的根本信息、数据库配置信息等。
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 configtype 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 configtype 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 configtype configData struct { DB mysqlConfig `json:"mysql"` Server serverConfig `json:"server"`}
这个示意config.json的整体构造。
用构造体解析json
解析json须要一些函数来反对,咱们将这些函数都写在config.go 外面。
定义变量
var ExecPath stringvar JsonData configDatavar ServerConfig serverConfigvar 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 configimport ( "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 stringvar JsonData configDatavar ServerConfig serverConfigvar DB *gorm.DBfunc 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 tidygo mod vendor
残缺的我的项目示例代码托管在GitHub上,须要查看残缺的我的项目代码能够到github.com/fesiong/goblog 上查看,也能够间接fork一份来在下面做批改。