乐趣区

关于golang:基础配置篇我的博客项目配置文件数据和配置的读写处理

上一节,咱们曾经定义和创立了咱们须要的目录,和我的项目初始化。这一节咱们就能够开始编写博客配置性能了。

下面咱们提到,咱们的配置处理函数将寄存在 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 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 一份来在下面做批改。

退出移动版