Golang学习日志 ━━ gin-vue-admin实现多数据库db-list

gin-vue-admin是一套国人用golang开发的后台管理系统,值得推荐给大家,其前端使用element-ui,后端使用gin框架。
官网:https://www.gin-vue-admin.com/

在这里插入图片描述

应用场景
多应用平台在实际运用项目时一定是需要多数据库支持的,比如:

  1. 原生系统用一个数据库gva
  2. 内容管理系统用一个数据库cms(3万条数据,20张表)
  3. 论坛系统用一个数据库bbs(10万条数据,30张表)
  4. 会议系统用一个数据库meeting
  5. 审计系统用一个数据库audit(50万条数据,15张表)
  6. 测试用一个数据库test(不限)

看,随着时间的推移,数据量将越来越大,分库甚至分服务器一定是必然。
当然,如果你只是制作一个单一的应用,那么多数据库就意义不大了。

gin-vue-admin目前的版本已支持多数据库,应用起来也非常方便。
但官方文档只写了关键部分,没有写具体应用的方法。
在研究过gva原生代码并测试成功后,记录于此。

流程

  1. 配置多数据库参数: db-list
    在配置文件中新增 db-list 选项 db-list 是文件中 mysqlpymysql 的一个超集,为了兼容低版本,目前没有在页面初始化的时候直接生成到db-list中。
  2. “告知”当前用哪个数据库
    在正确配置db-list后,代码启动后可以根据配置的 alias-nameglobal.GetGlobalDBByDBName(alias-name) 或者 global.MustGetGlobalDBByDBName(alias-name) 获取db对象。
  3. 执行数据库操作

配置

gin-vue-admin/serve/config.yaml 中找到db-list 进行配置。
注意:

  1. - “破折号+空格”开头的数据组成一个数据库组,这是yaml的规则要求
  2. disable: true 表示禁用,如要启用该数据库,则应当使用false
  3. type 表示数据库的类型,目前支持mysql、pgsql、mssql、oracle
  4. alias-name 表示该库别名,其值在db-list中唯一,作用相当于索引号、ID号,调用时也需要用到该别名
  5. db-name 表示数据库名
...
db-list:
- disable: false
  type: "mysql"
  alias-name: "test1"
  path: "127.0.0.1"
  port: "3306"
  config: "charset=utf8mb4&parseTime=True&loc=Local"
  db-name: "testdb1"
  username: "xxxxxx"
  password: "yyyyyy"
  prefix: ""
  singular: false
  engine: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: "error"
  log-zap: false
- disable: true
  type: "mysql"
  alias-name: "test2"
  path: "127.0.0.1"
  port: "3306"
  config: "charset=utf8mb4&parseTime=True&loc=Local"
  db-name: "testdb2"
  username: "aaaaaa"
  password: "bbbbbb"
  prefix: ""
  singular: false
  engine: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: "error"
  log-zap: false
...

选定数据库

参考 gin-vue-admin/server/global/global.go 中的两个函数,区别是 MustGetGlobalDBByDBName 会在alias-name不存在时 panic

// GetGlobalDBByDBName 通过名称获取db list中的db
func GetGlobalDBByDBName(dbname string) *gorm.DB {
	lock.RLock()
	defer lock.RUnlock()
	return GVA_DBList[dbname]
}

// MustGetGlobalDBByDBName 通过名称获取db 如果不存在则panic
func MustGetGlobalDBByDBName(dbname string) *gorm.DB {
	lock.RLock()
	defer lock.RUnlock()
	db, ok := GVA_DBList[dbname]
	if !ok || db == nil {
		panic("db no init")
	}
	return db
}

利用这两个函数中的一个就能选定数据库,下面看如何实现该操作。

实现操作

在某个 service 中增加一个函数:

func getDb(BusinessDb string) *gorm.DB {
	return global.MustGetGlobalDBByDBName(BusinessDb)
}

利用 getDb() 函数,将原数据库操作代码修改如下:

func CreateTest(data model.Test) (err error) {
	// 原操作数据方法,该方法使用系统默认数据库
	// err = global.GVA_DB.Create(&data).Error
	
	// 现在利用getDb()函数确定新的数据库后再执行操作
	err = getDb("test1").Create(&data).Error
	
	return err
}

看出 global.GBA_DB 的值和 getDb() 的返回值都是 *gorm.DB 没?其实原理就是修改 gorm.DB 值,修改了这个值,后续通过gorm 进行的操作就都在选定的数据库上执行了。

知道原理后自己写个选择数据库的函数也可以了吧?

一些注释

# github.com/flipped-aurora/gin-vue-admin/server Global Configuration

# jwt configuration
jwt:
  signing-key: qmPlus
  expires-time: 7d
  buffer-time: 1d
  issuer: qmPlus
# zap logger configuration
zap:
  level: info
  format: console
  prefix: "[github.com/flipped-aurora/gin-vue-admin/server]"
  director: log
  show-line: true
  encode-level: LowercaseColorLevelEncoder
  stacktrace-key: stacktrace
  log-in-console: true

# redis configuration
redis:
  db: 0
  addr: 127.0.0.1:6379
  password: ""

# email configuration
email:
  to: xxx@qq.com
  port: 465
  from: xxx@163.com
  host: smtp.163.com
  is-ssl: true
  secret: xxx
  nickname: test

# system configuration
system:
  env: public # Change to "develop" to skip authentication for development mode
  addr: 8888
  db-type: mysql
  oss-type: local # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
  use-redis: false # 使用redis
  use-multipoint: false
  # IP限制次数 一个小时15000次
  iplimit-count: 15000
  #  IP限制一个小时
  iplimit-time: 3600
  #  路由全局前缀
  router-prefix: ""

# captcha configuration
captcha:
  key-long: 6
  img-width: 240
  img-height: 80
  open-captcha: 0 # 0代表一直开启,大于0代表限制次数
  open-captcha-timeout: 3600 # open-captcha大于0时才生效

# mysql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
mysql:
  path: ""
  port: ""
  config: ""
  db-name: ""
  username: ""
  password: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: ""
  log-zap: false

# pgsql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
pgsql:
  path: ""
  port: ""
  config: ""
  db-name: ""
  username: ""
  password: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: ""
  log-zap: false
oracle:
  path: ""
  port: ""
  config: ""
  db-name: ""
  username: ""
  password: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: ""
  log-zap: false
mssql:
  path: ""
  port: ""
  config: ""
  db-name: ""
  username: ""
  password: ""
  max-idle-conns: 10
  max-open-conns: 100
  log-mode: ""
  log-zap: false
db-list:
  - disable: true # 是否禁用
    type: "" # 数据库的类型,目前支持mysql、pgsql、mssql、oracle
    alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
    path: ""
    port: ""
    config: ""
    db-name: ""
    username: ""
    password: ""
    max-idle-conns: 10
    max-open-conns: 100
    log-mode: ""
    log-zap: false

# local configuration
local:
  path: uploads/file
  store-path: uploads/file

# autocode configuration
autocode:
  transfer-restart: true
  # root 自动适配项目根目录
  # 请不要手动配置,他会在项目加载的时候识别出根路径
  root: ""
  server: /server
  server-plug: /plugin/%s
  server-api: /api/v1/%s
  server-initialize: /initialize
  server-model: /model/%s
  server-request: /model/%s/request/
  server-router: /router/%s
  server-service: /service/%s
  web: /web/src
  web-api: /api
  web-form: /view
  web-table: /view

# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
  zone: ZoneHuaDong
  bucket: ""
  img-path: ""
  use-https: false
  access-key: ""
  secret-key: ""
  use-cdn-domains: false

# aliyun oss configuration
aliyun-oss:
  endpoint: yourEndpoint
  access-key-id: yourAccessKeyId
  access-key-secret: yourAccessKeySecret
  bucket-name: yourBucketName
  bucket-url: yourBucketUrl
  base-path: yourBasePath

# tencent cos configuration
tencent-cos:
  bucket: xxxxx-10005608
  region: ap-shanghai
  secret-id: your-secret-id
  secret-key: your-secret-key
  base-url: https://gin.vue.admin
  path-prefix: github.com/flipped-aurora/gin-vue-admin/server

# aws s3 configuration (minio compatible)
aws-s3:
  bucket: xxxxx-10005608
  region: ap-shanghai
  endpoint: ""
  s3-force-path-style: false
  disable-ssl: false
  secret-id: your-secret-id
  secret-key: your-secret-key
  base-url: https://gin.vue.admin
  path-prefix: github.com/flipped-aurora/gin-vue-admin/server

# huawei obs configuration
hua-wei-obs:
  path: you-path
  bucket: you-bucket
  endpoint: you-endpoint
  access-key: you-access-key
  secret-key: you-secret-key

# excel configuration
excel:
  dir: ./resource/excel/

# timer task db clear table
Timer:
  start: true
  spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3
  detail:
    - tableName: sys_operation_records
      compareField: created_at
      interval: 2160h
    - tableName: jwt_blacklists
      compareField: created_at
      interval: 168h

# 跨域配置
# 需要配合 server/initialize/router.go#L32 使用
cors:
  mode: strict-whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
  whitelist:
    - allow-origin: example1.com
      allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id
      allow-methods: POST, GET
      expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type

      allow-credentials: true # 布尔值
    - allow-origin: example2.com
      allow-headers: content-type
      allow-methods: GET, POST
      expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
      allow-credentials: true # 布尔值

参考:
官网:多数据库支持
gin-vue-admin/server/config.yaml
一文看懂 YAML

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值