- Created by 郭强, last modified on Nov 11, 2022
配置文件
我们推荐使用配置组件来管理数据库配置,并使用g
对象管理模块中的g.DB("数据库分组名称")
方法获取数据库操作对象,数据库对象将会自动读取配置组件中的相应配置项,并自动初始化该数据库操作的单例对象。数据库配置管理功能使用的是配置管理组件实现(配置组件采用接口化设计默认使用文件系统实现),同样支持多种数据格式如:toml/yaml/json/xml/ini/properties
。默认并且推荐的配置文件数据格式为yaml
。
简单配置
从v2.2.0
版本开始,使用link
进行数据库配置时,数据库组件统一了不同数据库类型的配置格式,以简化配置管理。
简化配置通过配置项link
指定,格式如下:
type:username:password@protocol(address)[/dbname][?param1=value1&...¶mN=valueN]
即:
类型:账号:密码@协议(地址)/数据库名称?特性配置
其中:
- 数据库名称 及 特性配置为非必须参数,其他参数为必须参数。
- 协议可选配置为:
tcp/udp/file
,常见配置为tcp
- 特性配置根据不同的数据库类型,由其底层实现的第三方驱动定义,具体需要参考第三方驱动官网。例如,针对
mysql
驱动而言,使用的第三方驱动为:https://github.com/go-sql-driver/mysql 支持的特性配置如multiStatements
和loc
等。
示例:
database: default: link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test" user: link: "sqlite::@file(/var/data/db.sqlite3)"
不同数据类型对应的link
示例如下:
类型 | link示例 | 更多参数 |
---|---|---|
mysql | mysql:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=true | mysql |
mariadb | mariadb:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=true | mysql |
tidb | tidb:root:12345678@tcp(127.0.0.1:3306)/test?loc=Local&parseTime=true | mysql |
pgsql | pgsql:root:12345678@tcp(127.0.0.1:5432)/test | pq |
mssql |
| go-mssqldb |
sqlite | sqlite::@file(/var/data/db.sqlite3) | go-sqlite3 |
oracle | oracle:root:12345678@tcp(127.0.0.1:5432)/test | go-oci8 |
clickhouse | clickhouse:root:12345678@tcp(127.0.0.1:9000)/test | |
dm | dm:root:12345678@tcp(127.0.0.1:5236)/test |
框架支持的数据库类型请参考:https://github.com/gogf/gf/tree/master/contrib/drivers
完整配置
完整的config.yaml
数据库配置项的数据格式形如下:
database: 分组名称: host: "地址" port: "端口" user: "账号" pass: "密码" name: "数据库名称" type: "数据库类型(如:mariadb/tidb/mysql/pgsql/mssql/sqlite/oracle/clickhouse/dm)" link: "(可选)自定义数据库链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效,但是type必须有值" extra: "(可选)不同数据库的额外特性配置,由底层数据库driver定义" role: "(可选)数据库主从角色(master/slave),不使用应用层的主从机制请均设置为master" debug: "(可选)开启调试模式" prefix: "(可选)表名前缀" dryRun: "(可选)ORM空跑(只读不写)" charset: "(可选)数据库编码(如: utf8/gbk/gb2312),一般设置为utf8" weight: "(可选)负载均衡权重,用于负载均衡控制,不使用应用层的负载均衡机制请置空" timezone: "(可选)时区配置,例如:local" maxIdle: "(可选)连接池最大闲置的连接数" maxOpen: "(可选)连接池最大打开的连接数" maxLifetime: "(可选)连接对象可重复使用的时间长度" createdAt: "(可选)自动创建时间字段名称" updatedAt: "(可选)自动更新时间字段名称" deletedAt: "(可选)软删除时间字段名称" timeMaintainDisabled: "(可选)是否完全关闭时间更新特性,true时CreatedAt/UpdatedAt/DeletedAt都将失效"
完整的数据库配置项示例(YAML
):
database: default: host: "127.0.0.1" port: "3306" user: "root" pass: "12345678" name: "test" type: "mysql" 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"
使用该配置方式时,为保证数据库安全,默认底层不支持多行SQL
语句执行。为了得到更多配置项控制,请参考推荐的简化配置,同时建议您务必了解清楚简化配置项中每个连接参数的功能作用。
集群模式
gdb
的配置支持集群模式,数据库配置中每一项分组配置均可以是多个节点,支持负载均衡权重策略,例如:
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"
以上数据库配置示例中包含两个数据库分组default
和user
,其中default
分组包含一主一从,user
分组包含一主两从。在代码中可以通过g.DB()
和g.DB("user")
获取对应的数据库连接对象。
日志配置
gdb
支持日志输出,内部使用的是glog.Logger
对象实现日志管理,并且可以通过配置文件对日志对象进行配置。默认情况下gdb
关闭了DEBUG
日志输出,如果需要打开DEBUG
信息需要将数据库的debug
参数设置为true
。以下是为一个配置文件示例:
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
的日志配置,当该配置不存在时,将会使用日志组件的默认配置,具体请参考 日志组件-配置管理 章节。
需要注意哦:由于ORM
底层都是采用安全的预处理执行方式,提交到底层的SQL
与参数其实是分开的,因此日志中记录的完整SQL
仅作参考方便人工阅读,并不是真正提交到底层的SQL
语句。
原生配置(高阶,可选)
以下为数据库底层管理配置介绍,如果您对数据库的底层配置管理比较感兴趣,可继续阅读后续章节。
数据结构
gdb
数据库管理模块的内部配置管理数据结构如下:
ConfigNode
用于存储一个数据库节点信息;ConfigGroup
用于管理多个数据库节点组成的配置分组(一般一个分组对应一个业务数据库集群);Config
用于管理多个ConfigGroup
配置分组。
配置管理特点:
- 支持多节点数据库集群管理;
- 每个节点可以单独配置连接属性;
- 采用单例模式管理数据库实例化对象;
- 支持对数据库集群分组管理,按照分组名称获取实例化的数据库操作对象;
- 支持多种关系型数据库管理,可通过
ConfigNode.Type
属性进行配置; - 支持
Master-Slave
读写分离,可通过ConfigNode.Role
属性进行配置; - 支持客户端的负载均衡管理,可通过
ConfigNode.Weight
属性进行配置,值越大,优先级越高;
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)将失效(该字段是一个扩展功能) Extra string // (可选)不同数据库的额外特性配置,由底层数据库driver定义 Role string // (可选,默认为master)数据库的角色,用于主从操作分离,至少需要有一个master,参数值:master, slave Debug bool // (可选)开启调试模式 Charset string // (可选,默认为 utf8)编码,默认为 utf8 Prefix string // (可选)表名前缀 Weight int // (可选)用于负载均衡的权重计算,当集群中只有一个节点时,权重没有任何意义 MaxIdleConnCount int // (可选)连接池最大闲置的连接数 MaxOpenConnCount int // (可选)连接池最大打开的连接数 MaxConnLifetime time.Duration // (可选,单位秒)连接对象可重复使用的时间长度 }
特别说明,gdb
的配置管理最大的特点是,(同一进程中)所有的数据库集群信息都使用同一个配置管理模块进行统一维护,不同业务的数据库集群配置使用不同的分组名称进行配置和获取。
配置方法
这是原生调用gdb
模块来配置管理数据库。如果开发者想要自行控制数据库配置管理可以参考以下方法。若无需要可忽略该章节。
接口文档: https://pkg.go.dev/github.com/gogf/gf/v2/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.NewByGroup()
可获取一个默认分组的数据库对象。简单的做法,我们可以通过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.NewByGroup("数据库分组名称")
来获取一个数据库操作对象。该对象用于后续的数据库一系列方法/链式操作。
- No labels
15 Comments
朱华 Hunk
在v2下使用sqlite时,使用该文档所述的link格式 (即sqlite::@file(文件名) ),结果一直报error14,打不开数据库。后面采用 sqlite: 文件名,则成功打开数据库。文档这里关于sqlite的使用是否存在问题?
郭强
这个格式是从
v2.2
版本开始支持,请使用最新版本框架。zuns
配置中的updatedAt 自动更新的值是个字符串 “2022-10-14 13:46:09” 有没有指定用时间戳来替代该字符串时间的配置
18lkdev
郭强 这里时间戳自己转?
扶程星云
oracle
mssql:root:12345678@tcp(127.0.0.1:5432)/test
这个是错的吧,https://gfcdn.johng.cn 和 https://goframe.org/ 不同
MagicGirlYoYo
使用pgsql的时候报:Error: missing "=" after "postgres:123456@tcp(localhost:5432)/dev_db" in connection info string"
郭强
仔细看下文档
pgsql:root:12345678@tcp(127.0.0.1:5432)/test
MagicGirlYoYo
我的数据库配置是这样的
郭强
也要同时升级driver:
go get -u github.com/gogf/gf/contrib/drivers/mysql/v2
MagicGirlYoYo
感谢老哥,升级一下就没问题了
cbqi
这个有类似gorm的migration功能吗,表还是要自己提前创建好吗,那修改表结构不是很麻烦
wangshuai
连接clickhouse查询数据,请问这个错误和版本有关系嘛
CLI Built Detail:
Go Version: go1.19.2
GF Version: v2.2.5
Git Commit: none
Build Time: 2022-11-29 16:16:54
clickhouse版本:22.2.2
配置文件:
异常日志:
[clickhouse][conn=1][XXX.XXX.XXX.XXX:9000][send query] compression=%!t(clickhouse.CompressionMethod=2) select * from 表名 where name= 'sss'
[clickhouse][conn=1][XXX.XXX.XXX.XXX:9000][send data] compression=%!t(clickhouse.CompressionMethod=2)
[clickhouse][conn=1][XXX.XXX.XXX.XXX:9000][exception] code: 115, message: Unknown setting charset
2022-11-30 11:17:18.817 [ERRO] {285d7715763e2c1752303151bcfd403a} [ 80 ms] [ck] [default] [rows:0 ] select * from 表名 where name= 'sss'
Error: code: 115, message: Unknown setting charset
咸鱼老罗
sqlite数据库在开发模式下可以使用相对路径,相对路径由项目路径开始
下面配置将会读取文件的路径:项目文件夹/manifest/document/sqlite/focus.db
database:
default:
link: "sqlite::@file(manifest/document/sqlite/focus.db)"
老五
请问 有支持 elasticsearch 的打算吗
如果短期内没有该打算,能否提供下集成的相关文档,项目当中用到es,现在用的是restful api,想集成 https://github.com/elastic/go-elasticsearch 到项目里
糖水不加糖
ORM接口开发-驱动开发