Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

配置文件

Tip

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

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

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

完整配置

方法获取数据库操作对象,数据库对象将会自动读取配置组件中的相应配置项,并自动初始化该数据库操作的单例对象。数据库配置管理功能使用的是配置管理组件实现(配置组件采用接口化设计默认使用文件系统实现),同样支持多种数据格式如:toml/yaml/json/xml/ini/properties。默认并且推荐的配置文件数据格式为yaml

简单配置

Tip

v2.2.0版本开始,使用link进行数据库配置时,数据库组件统一了不同数据库类型的配置格式,以简化配置管理。

简化配置通过配置项link指定,格式如下:完整的config.toml数据库配置项的数据格式形如下:

Code Block
languagetomlxml
type:username:password@protocol(address)[/dbname][?param1=value1&...&paramN=valueN]

即:

Code Block
languagexml
类型:账号:密码@协议(地址)/数据库名称?特性配置

其中:

  • 数据库名称 特性配置为非必须参数,其他参数为必须参数。
  • 协议可选配置为:tcp/udp/file,常见配置为tcp
  • 特性配置根据不同的数据库类型,由其底层实现的第三方驱动定义,具体需要参考第三方驱动官网。例如,针对mysql驱动而言,使用的第三方驱动为:https://github.com/go-sql-driver/mysql 支持的特性配置如multiStatementsloc等。

示例:

Code Block
languageyml
database:
  default:
    link:  "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
  user:
    link:  "sqlite::@file(/var/data/db.sqlite3)"

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

类型link示例extra参数
mysqlmysql:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=truemysql
mariadbmariadb:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=truemysql
tidbtidb:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=truemysql
pgsqlpgsql:root:12345678@tcp(127.0.0.1:5432)/testpq
mssql

mssql:root:12345678@tcp(127.0.0.1:1433)/test?encrypt=disable

go-mssqldb
sqlitesqlite::@file(/var/data/db.sqlite3)  (可以使用相对路径,如:db.sqlite3)go-sqlite3
oracleoracle:root:12345678@tcp(127.0.0.1:5432)/testgo-oci8
clickhouseclickhouse:root:12345678@tcp(127.0.0.1:9000)/test

clickhouse-go

dmdm:root:12345678@tcp(127.0.0.1:5236)/test

dm


Tip

更多框架支持的数据库类型请参考:https://github.com/gogf/gf/tree/master/contrib/drivers

完整配置

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

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

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

[database]
不同数据库的额外特性配置,由底层数据库driver定义"
    
[[database.default]]
role:        
host
         
= "127.0.0.1"
 "(可选)数据库主从角色(master/slave),不使用应用层的主从机制请均设置为master"
    debug:       
port
         
=
 "
3306
(可选)开启调试模式"
    prefix:    
user
         
=
   "
root
(可选)表名前缀"
    dryRun:     
pass
          
=
 "
12345678
(可选)ORM空跑(只读不写)"
    charset:     
name
         
=
 "
test"
(可选)数据库编码(如: utf8/gbk/gb2312),一般设置为utf8"
	protocol:    
type
         
=
 "
mysql
(可选)数据库连接协议,默认为TCP"
    weight:      
role
         
=
 "
master
(可选)负载均衡权重,用于负载均衡控制,不使用应用层的负载均衡机制请置空"
    timezone:     
debug
        
=
 "
true
(可选)时区配置,例如:local"
    namespace:     
dryrun
       
= 1
 "(可选)用以支持个别数据库服务Catalog&Schema区分的问题,原有的Schema代表数据库名称,而NameSpace代表个别数据库服务的Schema"
    maxIdle:       
weight
       
=
 "
100
(可选)连接池最大闲置的连接数(默认10)"
    maxOpen:    
prefix
       
=
 
"gf_"
   
charset = "utf8
"(可选)连接池最大打开的连接数(默认无限制)"
    maxLifetime:    
linkinfo
      
=
 "(可选)连接对象可重复使用的时间长度(默认30秒)"
	queryTimeout:       
maxIdle
   
= "10" maxOpen = "100"
"(可选)查询语句超时时长(默认无限制,注意ctx的超时时间设置)"
	execTimeout:           "(可选)写入语句超时时长(默认无限制,注意ctx的超时时间设置)"
	tranTimeout:           "(可选)事务处理超时时长(默认无限制,注意ctx的超时时间设置)"
	prepareTimeout:        "(可选)预准备SQL语句执行超时时长(默认无限制,注意ctx的超时时间设置)""
    createdAt:         
maxLifetime
   
=
 "
30"
Tip

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

简化配置(推荐)

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

[database]
(可选)自动创建时间字段名称"
    
[[database.default]]
updatedAt:           
type
 
=
 "
mysql
(可选)自动更新时间字段名称"
    deletedAt:           
link
 
=
 "
root:12345678@tcp(127.0.0.1:3306)/test
(可选)软删除时间字段名称"
  
[[database.user]]
  timeMaintainDisabled:  "(可选)是否完全关闭时间更新特性,true时CreatedAt/UpdatedAt/DeletedAt都将失效"

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

Code Block
languageyml
database:
  default:
    host:  
type
 
=
 
"mysql"
      
link = "mysql:root:12345678@tcp(127
"127.0.0.1
:3306)/user
"

也可以简化为:

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

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

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

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

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

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

类型link配置更多参数mysqlmysql: 账号:密码@tcp(地址:端口)/数据库名称mysqlpgsqlpgsql: user=账号 password=密码 host=地址 port=端口 dbname=数据库名称pqmssqlmssql: user id=账号;password=密码;server=地址;port=端口;database=数据库名称;encrypt=disablego-mssqldbsqlitesqlite: 文件绝对路径 (如: /var/lib/db.sqlite3)go-sqlite3oracleoracle: 账号/密码@地址:端口/数据库名称go-oci8
"
    extra:         "local=Local&parseTime=true"
    role:          "master"
    debug:         "true"
    dryrun:        0
    weight:        "100"
    prefix:        "gf_"
    charset:       "utf8"
    timezone:      "local"
    maxIdle:       "10"
    maxOpen:       "100"
    maxLifetime:   "30s"
 	protocol


Info

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

集群模式

gdb的配置支持集群模式,数据库配置中每一项分组配置均可以是多个节点,支持负载均衡权重策略,例如:

Code Block
languageyml
database:
  default:
  - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
    role: "master"
  - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
    role: "slave"

  user:
  - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/user"
    role: "master"
  - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/user"
    role: "slave"
  - link: "mysql:root:12345678@tcp(127.0.0.1:3306)/user"
    role: "slave"

以上数据库配置示例中包含两个数据库分组defaultuser,其中default分组包含一主一从,user分组包含一主两从。在代码中可以通过g.DB()g.DB("user")获取对应的数据库连接对象。

日志配置

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

Code Block
languageyml
database:
  logger:
    path:    "/var/log/gf-app/sql"
    level:   "all"
    stdout:  true
  default:
    link:    "mysql:root:12345678@tcp(127.0.0.1:3306)/user_center"
    debug:   true

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

Note

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

原生配置(高阶,可选)

Tip

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

数据结构

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

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

配置管理特点:

  1. 支持多节点数据库集群管理;
  2. 每个节点可以单独配置连接属性;
  3. 采用单例模式管理数据库实例化对象;
  4. 支持对数据库集群分组管理,按照分组名称获取实例化的数据库操作对象;
  5. 支持多种关系型数据库管理,可通过ConfigNode.Type属性进行配置;
  6. 支持Master-Slave读写分离,可通过ConfigNode.Role属性进行配置;
  7. 支持客户端的负载均衡管理,可通过ConfigNode.Weight属性进行配置,值越大,优先级越高;
Code Block
languagego
type Config      map[string]ConfigGroup // 数据库配置对象
type ConfigGroup []ConfigNode           // 数据库分组配置
// 数据库配置项(一个分组配置对应多个配置项)
type ConfigNode  struct {
    Host             string        // 地址
    Port             string        // 端口
    User             string        // 账号
    Pass             string        // 密码
    Name             string        // 数据库名称
    Type             string

各数据库类型更详细的linkinfo参数信息请查看对应引擎官网,参考 数据库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的日志配置,当该配置不存在时,将会使用日志组件的默认配置,具体请参考 日志组件 章节。

Note

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

原生配置(高阶,可选)

Tip

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

数据结构

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

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

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

配置方法

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

接口文档: https://pkg.go.dev/github.com/gogf/gf/v2/database/gdb

Code Block
languagego
// 添加一个数据库节点到指定的分组中
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.NewByGroup()可获取一个默认分组的数据库对象。简单的做法,我们可以通过gdb包的SetConfig配置管理方法进行自定义的数据库全局配置,例如:

Code Block
languagego
gdb.SetConfig(gdb.Config {
    "default" : gdb.ConfigGroup {
        gdb.ConfigNode {
            Host     : "192.168.1.100",
            Port     : "3306",
            User     : "root",
            Pass     : "123456",
            Name     : "test",

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

配置管理特点:

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

特别说明,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
Type     : "
192.168.1.100
mysql",
            
Port
Role     : "
3306"
master",
            Weight   : 100,
        },
    
User
    
: "root",
gdb.ConfigNode {
            
Pass
Host     : "
123456
192.168.1.101",
            
Name
Port     : "
test
3306",
            
Type
User     : "
mysql
root",
            
Role
Pass     : "
master
123456",
            Name  
Weight
   : 
100
"test",
        
},
    Type    
gdb.ConfigNode {
 : "mysql",
            
Host
Role     : 
"192.168.1.101
"slave",
            Weight   : 100,
  
Port
     
:
 
"3306"
},
    },
    "user-center" : gdb.ConfigGroup {
   
User
     
: "root",
gdb.ConfigNode {
            
Pass
Host     : "
123456
192.168.1.110",
            
Name
Port     : "
test
3306",
            
Type
User     : "
mysql
root",
            
Role
Pass     : "
slave
123456",
            Name  
Weight
   : 
100
"test",
        
},
    
},
Type    
"user-center"
 : 
gdb.ConfigGroup {
"mysql",
        
gdb.ConfigNode
 
{
   
Host
Role     
: 
"192.168.1.110
"master",
            
Port
Weight   
: 
"3306"
100,
        },
    
User : "root", Pass : "123456", Name : "test", Type : "mysql", Role : "master", Weight : 100, }, }, }) 随后,我们可以使用gdb.New("数据库分组名称")来获取一个数据库操作对象。该对象用于后续的数据库一系列方法/链式操作。
},
})

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

常见问题

如何实现数据库账号密码在配置文件中加密

在某些场景下,数据库的账号密码无法明文配置到配置文件中,需要进行一定的加密。在连接数据库的时候,再对配置文件中加密的字段进行解密处理。这种需求可以通过自定义Driver来实现(关于Driver的详细介绍请参考章节:ORM接口开发)。以mysql为例,我们可以自己编写一个Driver,包裹框架社区组件中的mysql driver,并且覆盖它的Open方法即可。代码示例:

Code Block
languagego
import (
	"database/sql"

	"github.com/gogf/gf/contrib/drivers/mysql/v2"
	"github.com/gogf/gf/v2/database/gdb"
)

type MyBizDriver struct {
	mysql.Driver
}

// Open creates and returns an underlying sql.DB object for mysql.
// Note that it converts time.Time argument to local timezone in default.
func (d *MyBizDriver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
	config.User = d.decode(config.User)
	config.Pass = d.decode(config.Pass)
	return d.Driver.Open(config)
}

func (d *MyBizDriver) decode(s string) string {
	// 执行字段解密处理逻辑
	// ...
	return s
}




Panel
titleContent Menu

Table of Contents