配置文件

推荐使用配置文件及单例对象来管理和使用数据库操作。

如果我们使用g对象管理模块中的g.DB("数据库分组名称")方法获取数据库操作对象,数据库对象将会自动读取config.toml配置文件中的相应配置项(通过配置管理模块),并自动初始化该数据库操作的单例对象。

数据库配置管理功能使用的是配置管理模块实现,因此同样支持多种数据格式如:toml, yaml, json, xml。默认并且推荐的配置文件数据格式为toml

篇幅有限,这里仅展示了推荐的toml格式的文件示例格式,其他配置文件的数据格式请自行研究。

完整配置

完整的config.toml数据库配置项的数据格式形如下:

[database]
    [[database.分组名称]]
        host                 = "地址"
        port                 = "端口"
        user                 = "账号"
        pass                 = "密码"
        name                 = "数据库名称"
        type                 = "数据库类型(mysql/pgsql/mssql/sqlite/oracle)"
        link                 = "(可选)自定义数据库链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效,但是type必须有值"         role                 = "(可选)数据库主从角色(master/slave),不使用应用层的主从机制请均设置为master"
        debug                = "(可选)开启调试模式"
        prefix               = "(可选)表名前缀"
        dryRun               = "(可选)ORM空跑(只读不写)"
        charset              = "(可选)数据库编码(如: utf8/gbk/gb2312),一般设置为utf8"
        weight               = "(可选)负载均衡权重,用于负载均衡控制,不使用应用层的负载均衡机制请置空"
        maxIdle              = "(可选)连接池最大闲置的连接数"
        maxOpen              = "(可选)连接池最大打开的连接数"
        maxLifetime          = "(可选)连接对象可重复使用的时间长度"
        createdAt            = "(可选)自动创建时间字段名称"
	    updatedAt            = "(可选)自动更新时间字段名称"
	    deletedAt            = "(可选)软删除时间字段名称"
        timeMaintainDisabled = "(可选)是否完全关闭时间更新特性,true时CreatedAt/UpdatedAt/DeletedAt都将失效"

完整的数据库配置项示例(TOML):

[database]
    [[database.default]]
        host         = "127.0.0.1"
        port         = "3306"
        user         = "root"
        pass         = "12345678"
        name         = "test"
        type         = "mysql"
        role         = "master"
        debug        = "true"
        dryrun       = 1
        weight       = "100"
        prefix       = "gf_"
        charset      = "utf8"
        maxIdle      = "10"
        maxOpen      = "100"
        maxLifetime  = "30s"

使用该配置方式时,为保证数据库安全,默认底层不支持多行SQL语句执行。为了得到更多配置项控制,请参考推荐的简化配置,同时建议您务必了解清楚简化配置项中每个连接参数的功能作用。

简化配置(推荐)

为兼容不同的数据库类型,gdb将数据库的各个字段拆分出来单独配置,这样对于各种数据库的对接来说兼容性会很好。但是对于开发者来说看起来配置比较多。针对于项目中使用的已确定的数据库类型的配置,我们可以使用link属性进行配置。如:

[database]
    [[database.default]]
        type = "mysql"
        link = "root:12345678@tcp(127.0.0.1:3306)/test"
    [[database.user]]
        type = "mysql"
        link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"

也可以简化为:

[database]
    [[database.default]]
        link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
    [[database.user]]
        link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"

注意以上每一项分组配置均可以是多个节点,支持负载均衡权重策略。如果不使用多节点负载均衡特性,仅使用配置分组特性,也可以简化为如下格式:

[database]
    [database.default]
        link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
    [database.user]
        link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"

如果仅仅是单数据库节点,不使用配置分组特性,那么也可以简化为如下格式:

[database]
    link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"

配置文件database节点中的配置项使用数组类型或键值对类型都是能被ORM组件自动识别支持的。大部分场景中,不使用客户端层面的负载均衡和读写分离等集群特性,那么都可以使用键值对配置,每个数据库分组只有一项数据库配置。

不同数据类型对应的link如下:

类型link配置更多参数
mysqlmysql: 账号:密码@tcp(地址:端口)/数据库名称mysql
pgsqlpgsql: user=账号 password=密码 host=地址 port=端口 dbname=数据库名称pq
mssqlmssql: user id=账号;password=密码;server=地址;port=端口;database=数据库名称;encrypt=disablego-mssqldb
sqlitesqlite: 文件绝对路径 (如: /var/lib/db.sqlite3)go-sqlite3
oracleoracle: 账号/密码@地址:端口/数据库名称go-oci8

各数据库类型更详细的link参数信息请查看对应引擎官网,参考 数据库ORM 章节。

日志输出配置

gdb支持日志输出,内部使用的是glog.Logger对象实现日志管理,并且可以通过配置文件对日志对象进行配置。默认情况下gdb关闭了DEBUG日志输出,如果需要打开DEBUG信息需要将数据库的debug参数设置为true。以下是为一个配置文件示例:

[database]
    [database.logger]
        path   = "/var/log/gf-app/sql"
        level  = "all"
        stdout = true
    [database.primary]
        link   = "mysql:root:12345678@tcp(127.0.0.1:3306)/user_center"
        debug  = true

其中database.logger即为gdb的日志配置,当该配置不存在时,将会使用日志组件的默认配置,具体请参考 日志组件 章节。

需要注意哦:由于ORM底层都是采用安全的预处理执行方式,提交到底层的SQL与参数其实是分开的,因此日志中记录的完整SQL仅作参考方便人工阅读,并不是真正提交到底层的SQL语句。

原生配置(高阶,可选)

以下为数据库底层管理配置介绍,如果您对数据库的底层配置管理比较感兴趣,可继续阅读后续章节。

数据结构

gdb数据库管理模块的内部配置管理数据结构如下:

type Config      map[string]ConfigGroup // 数据库配置对象
type ConfigGroup []ConfigNode           // 数据库分组配置
// 数据库配置项(一个分组配置对应多个配置项)
type ConfigNode  struct {
    Host             string        // 地址
    Port             string        // 端口
    User             string        // 账号
    Pass             string        // 密码
    Name             string        // 数据库名称
    Type             string        // 数据库类型:mysql, sqlite, mssql, pgsql, oracle
Link string // (可选)自定义链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效(该字段是一个扩展功能)     Role string // (可选,默认为master)数据库的角色,用于主从操作分离,至少需要有一个master,参数值:master, slave Debug bool // (可选)开启调试模式 Charset string // (可选,默认为 utf8)编码,默认为 utf8 Prefix string // (可选)表名前缀 Weight int // (可选)用于负载均衡的权重计算,当集群中只有一个节点时,权重没有任何意义 MaxIdleConnCount int // (可选)连接池最大闲置的连接数 MaxOpenConnCount int // (可选)连接池最大打开的连接数 MaxConnLifetime time.Duration // (可选,单位秒)连接对象可重复使用的时间长度 }

ConfigNode用于存储一个数据库节点信息;ConfigGroup用于管理多个数据库节点组成的配置分组(一般一个分组对应一个业务数据库集群);Config用于管理多个ConfigGroup配置分组。

配置管理特点:

  1. 支持多节点数据库集群管理;
  2. 每个节点可以单独配置连接属性;
  3. 采用单例模式管理数据库实例化对象;
  4. 支持对数据库集群分组管理,按照分组名称获取实例化的数据库操作对象;
  5. 支持多种关系型数据库管理,可通过ConfigNode.Type属性进行配置;
  6. 支持Master-Slave读写分离,可通过ConfigNode.Role属性进行配置;
  7. 支持客户端的负载均衡管理,可通过ConfigNode.Weight属性进行配置,值越大,优先级越高;

特别说明,gdb的配置管理最大的特点是,(同一进程中)所有的数据库集群信息都使用同一个配置管理模块进行统一维护,不同业务的数据库集群配置使用不同的分组名称进行配置和获取。

配置方法

这是原生调用gdb模块来配置管理数据库。如果开发者想要自行控制数据库配置管理可以参考以下方法。若无需要可忽略该章节。

接口文档: https://godoc.org/github.com/gogf/gf/database/gdb

// 添加一个数据库节点到指定的分组中
func AddConfigNode(group string, node ConfigNode)
// 添加一个配置分组到数据库配置管理中(同名覆盖)
func AddConfigGroup(group string, nodes ConfigGroup)

// 添加一个数据库节点到默认的分组中(默认为default,可修改)
func AddDefaultConfigNode(node ConfigNode)
// 添加一个配置分组到数据库配置管理中(默认分组为default,可修改)
func AddDefaultConfigGroup(nodes ConfigGroup)

// 设置默认的分组名称,获取默认数据库对象时将会自动读取该分组配置
func SetDefaultGroup(groupName string)

// 设置数据库配置为定义的配置信息,会将原有配置覆盖
func SetConfig(c Config)

默认分组表示,如果获取数据库对象时不指定配置分组名称,那么gdb默认读取的配置分组。例如:gdb.New()可获取一个默认分组的数据库对象。

简单的做法,我们可以通过gdb包的SetConfig配置管理方法进行自定义的数据库全局配置,例如:

gdb.SetConfig(gdb.Config {
    "default" : gdb.ConfigGroup {
        gdb.ConfigNode {
            Host     : "192.168.1.100",
            Port     : "3306",
            User     : "root",
            Pass     : "123456",
            Name     : "test",
            Type     : "mysql",
            Role     : "master",
            Weight   : 100,
        },
        gdb.ConfigNode {
            Host     : "192.168.1.101",
            Port     : "3306",
            User     : "root",
            Pass     : "123456",
            Name     : "test",
            Type     : "mysql",
            Role     : "slave",
            Weight   : 100,
        },
    },
    "user-center" : gdb.ConfigGroup {
        gdb.ConfigNode {
            Host     : "192.168.1.110",
            Port     : "3306",
            User     : "root",
            Pass     : "123456",
            Name     : "test",
            Type     : "mysql",
            Role     : "master",
            Weight   : 100,
        },
    },
})

随后,我们可以使用gdb.New("数据库分组名称")来获取一个数据库操作对象。该对象用于后续的数据库一系列方法/链式操作。




Content Menu

  • No labels

15 Comments

  1. roy

    哈咯,关于日志我想咨询一下

    我这边有这样的需求,全量格式化json日志输出,并保留之前的输出方法api

    通过源码翻看,DB对象是有SetLogger的方法,但是是个glogstruct。这里是否能考虑改成interface呢?通过接口外放自定义输出能力。

    1. v1.17版本开始是interface接口类型。

  2. oracle的配置能不能增加一个比较详细的示例啊?

    1. ``` 

      [database]
      [[database.default]]
      host = "127.0.0.1"
      port = "1521"
      user = "user"
      pass = "pass"
      name = "orcl"
      type = "oracle"
      role = "master"
      charset = "utf-8"
      ```
      config.toml中使用上面的配置。

      例如tnsnames.ora如下
      ```
      ORCL =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.137.4)(PORT = 1521))
          (CONNECT_DATA =
          (SERVICE_NAME = orclsid)
          )
        )
      ```

      其中name是配置在监听文件中的的监听的名字。例如数据库的sid是orclsid,那么config.toml中的name就是orcl。


      另外,部署环境时建议直接安装oracle客户端,不要按照网上的下载单独的SDK,虽然SDK比较小,但是太麻烦,直接装客户端比较简单。

  3. sqlite该在gf-cli工具中如何配置?目前使用的数据库配置如下:

    [database]
        link = "sqlite:D:\\demo.db"

    gf-cli工具已经按照文档打开go-sqlite注释并编译,但具体到使用上面工程配置时,使用gf den dao一直报配置错误。

    1. 工具配置参考章节:gen dao(重点)

  4. 使用 db.model.one 去查询的时候,返回的错误对象中提示 NextBytes InitializeSecurityContext failed 8009030e 请问这个是什么问题呢?也没有返回数据 

    1. 找到问题啦,是数据库配置文件哪里,多加了一个type的字段

      如果这样配置,就会出问题:

      [database]
          [[database.default]]
              type = "mssql"
              link = "mssql:user id=sa;password=xxxxxxxx;server=xxxx.xxxx.xxxx.xxxx;port=1433;database=xxxxxxxx;encrypt=disable"

      这样就不会:

      [database]
          [[database.default]]
              link = "mssql:user id=sa;password=xxxxxxxx;server=xxxx.xxxx.xxxx.xxxx;port=1433;database=xxxxxxxx;encrypt=disable"

      可是教程上不是可以这么配置吗?
      难道是数据库不同的问题吗?
      这个数据库是 sqlserver

      1. ORM组件需要识别你配置的数据库类型,你可以通过在link字段中添加mssql的配置,也可以增加独立的type字段配置数据库类型。以下两种方式都是可以的:

        [database]
            [[database.default]]
                link = "mssql:user id=sa;password=xxxxxxxx;server=xxxx.xxxx.xxxx.xxxx;port=1433;database=xxxxxxxx;encrypt=disable"

        或者

        [database]
            [[database.default]]
                type = "mssql"
                link = "user id=sa;password=xxxxxxxx;server=xxxx.xxxx.xxxx.xxxx;port=1433;database=xxxxxxxx;encrypt=disable"
  5. orm的timeout当前是通过ctx去控制,是否应该做一个timeout的全局配置(默认超时控制),当orm显式的传入context.WithTimeout的时候在覆盖此次全局设置,或者干脆像httpclient一样直接开SetTimeout方法可全局可链式.

    就类似.net里的MysqlCommand.CommandTimeout = 5000 (毫秒).执行Sql语句的 执行时间 超过5000毫秒 就超时返回一个err

  6. Jay

    如何可以对敏感配置信息进行加密处理,并在初始化ORM时进行解密处理呢?

    1. 我觉得敏感信息配置你可以卸载golang 的代码里面,编译成二进制了...怕啥

      1. Jay

        主要是DB连接信息如果写在代码里,框架不是就不能通过读取配置文件的方式初始化db了呢

        1. 你这属于伪需求,  一般能改看你配置,也就能找你mysql 了,如果你不想有配置,你可以选择配置中心