基础配置篇(我的博客项目配置文件数据和配置的读写处理)
上一节,我们已经定义和创建了我们需要的目录,和项目初始化。这一节我们就可以开始编写博客配置功能了。
上面我们提到,我们的配置处理函数将存放在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级别的信息。
config.json
定义好并放到config目录后,我们还需要编写代码,让golang可以读取它,才能在项目中调用配置文件中的信息。这些文件我们都放置在config
文件夹中。为了方便程序读取,我们先给上面两个字段创建两个承载这些具体字段的结构体:
mysql.go
package configtype mysqlConfig struct {
Database string `json:"database"`
Userstring `json:"user"`
Password string `json:"password"`
Hoststring `json:"host"`
Portint`json:"port"`
Urlstring `json:"-"`
}
它对应的是刚才我们定义的json文件中的mysql字段。
结构体的定义是使用关键字 type 和 struct 来声明一个结构体,以关键字 type 开始,之后是新类型的名字,最后是关键字 struct。
结构体里的字段都有名字,比如上面例子中的 Database 和 User 等等。如果一个字段在代码中从来不会被用到,那可以把它命名为 _,即空标识符。
结构体变量采用大写可以从外部访问到,中间的string、int为这个字段的字段类型,``包含的内容为结构体字段指定一个标记信息,上面的标记表示是json字段的对应字段名称。
结构体中的字段可以是任何类型,甚至是结构体本身,也可以是函数或者接口。可以声明结构体类型的一个变量。
同一个包中,不能出现同名的结构体,不同包不受限制。
server.go
package configtype serverConfig struct {
SiteName string `json:"site_name"`
Envstring `json:"env"`
Portint`json:"port"`
LogLevel string `json:"log_level"`
}
server.go对应的的是json文件的server字段。
config.go
package configtype configData struct {
DBmysqlConfig`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 = dbreturn 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 {
DBmysqlConfig`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 = dbreturn nil
}func initServer() {
ServerConfig = JsonData.Server
}var ExecPath string
var JsonData configData
var ServerConfig serverConfig
var 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 tidy
go mod vendor
完整的项目示例代码托管在GitHub上,需要查看完整的项目代码可以到github.com/fesiong/goblog 上查看,也可以直接fork一份来在上面做修改。
推荐阅读
- 2018年11月19日|2018年11月19日 星期一 亲子日记第144篇
- vue-cli|vue-cli 3.x vue.config.js 配置
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 拍照一年啦,如果你想了解我,那就请先看看这篇文章
- 亲子日记第186篇,2018、7、26、星期四、晴
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 两短篇
- Python基础|Python基础 - 练习1
- 第四十三篇接纳孩子的感受
- 感恩日记第111篇2020.02.06