1 Star 0 Fork 0

余济舟/util

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
postgres_pool.go 5.16 KB
一键复制 编辑 原始数据 按行查看 历史
YuJizhou 提交于 2024-08-30 15:04 . [test]新增自研数据库连接池
package gormPool
import (
"fmt"
"sync"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/plugin/dbresolver"
)
type PostgresPool struct {
username string
password string
host string
port uint16
database string
maxIdleTime int
maxLifetime int
maxIdleConns int
maxOpenConns int
mainDsn *Dsn
mainConn *gorm.DB
sources map[string]*PostgresConnection
replicas map[string]*PostgresConnection
}
var (
postgresPoolIns *PostgresPool
postgresPoolOnce sync.Once
PostgresDsnFormat = "host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s"
PostgresPoolApp PostgresPool
)
// Once 单例化:postgres链接池
func (PostgresPool) Once(dbSetting *DbSetting) GormPool {
postgresPoolOnce.Do(func() {
postgresPoolIns = &PostgresPool{
username: dbSetting.Postgres.Main.Username,
password: dbSetting.Postgres.Main.Password,
host: dbSetting.Postgres.Main.Host,
port: dbSetting.Postgres.Main.Port,
database: dbSetting.Postgres.Main.Database,
maxIdleTime: dbSetting.Common.MaxIdleTime,
maxLifetime: dbSetting.Common.MaxLifetime,
maxIdleConns: dbSetting.Common.MaxIdleConnections,
maxOpenConns: dbSetting.Common.MaxOpenConnections,
}
})
var (
err error
dbConfig *gorm.Config
)
// 配置主库
postgresPoolIns.mainDsn = &Dsn{
Name: "main",
Content: fmt.Sprintf(
PostgresDsnFormat,
dbSetting.Postgres.Main.Host,
dbSetting.Postgres.Main.Username,
dbSetting.Postgres.Main.Password,
dbSetting.Postgres.Main.Database,
dbSetting.Postgres.Main.Port,
dbSetting.Postgres.Main.SslMode,
dbSetting.Postgres.Main.TimeZone,
),
}
// 数据库配置
dbConfig = &gorm.Config{
PrepareStmt: true, // 预编译
CreateBatchSize: 500, // 批量操作
DisableForeignKeyConstraintWhenMigrating: true, // 禁止自动创建外键
SkipDefaultTransaction: false, // 开启自动事务
QueryFields: true, // 查询字段
AllowGlobalUpdate: false, // 不允许全局修改,必须带有条件
}
// 配置主库
postgresPoolIns.mainConn, err = gorm.Open(postgres.Open(postgresPoolIns.mainDsn.Content), dbConfig)
if err != nil {
panic(fmt.Sprintf("配置数据库失败:%s", err.Error()))
}
postgresPoolIns.mainConn = postgresPoolIns.mainConn.Session(&gorm.Session{})
sqlDb, _ := postgresPoolIns.mainConn.DB()
sqlDb.SetConnMaxIdleTime(time.Duration(postgresPoolIns.maxIdleTime) * time.Hour)
sqlDb.SetConnMaxLifetime(time.Duration(postgresPoolIns.maxLifetime) * time.Hour)
sqlDb.SetMaxIdleConns(postgresPoolIns.maxIdleConns)
sqlDb.SetMaxOpenConns(postgresPoolIns.maxOpenConns)
return postgresPoolIns
}
// GetMain 获取主数据库链接
func (r *PostgresPool) GetConn() *gorm.DB {
r.getRws()
return r.mainConn
}
// getRws 获取带有读写分离的数据库链接
func (r *PostgresPool) getRws() *gorm.DB {
var (
err error
sourceDialectors, replicaDialectors []gorm.Dialector
sources []*Dsn
replicas []*Dsn
)
// 配置写库
if len(r.sources) > 0 {
sources = make([]*Dsn, 0)
for idx, item := range r.sources {
sources = append(sources, &Dsn{
Name: idx,
Content: fmt.Sprintf(
PostgresDsnFormat,
item.Host,
item.Username,
item.Password,
item.Database,
item.Port,
item.SslMode,
item.TimeZone,
),
})
}
}
// 配置读库
if len(r.replicas) > 0 {
replicas = make([]*Dsn, 0)
for idx, item := range r.replicas {
replicas = append(replicas, &Dsn{
Name: idx,
Content: fmt.Sprintf(
PostgresDsnFormat,
item.Host,
item.Username,
item.Password,
item.Database,
item.Port,
item.SslMode,
item.TimeZone,
),
})
}
}
if len(sources) > 0 {
sourceDialectors = make([]gorm.Dialector, len(sources))
for i := 0; i < len(sources); i++ {
sourceDialectors[i] = postgres.Open(sources[i].Content)
}
}
if len(replicas) > 0 {
replicaDialectors = make([]gorm.Dialector, len(replicas))
for i := 0; i < len(replicas); i++ {
replicaDialectors[i] = postgres.Open(replicas[i].Content)
}
}
err = r.mainConn.Use(
dbresolver.Register(dbresolver.Config{
Sources: sourceDialectors, // 写库
Replicas: replicaDialectors, // 读库
Policy: dbresolver.RandomPolicy{}, // 策略
TraceResolverMode: true,
}).
SetConnMaxIdleTime(time.Duration(r.maxIdleTime) * time.Hour).
SetConnMaxLifetime(time.Duration(r.maxLifetime) * time.Hour).
SetMaxIdleConns(r.maxIdleConns).
SetMaxOpenConns(r.maxOpenConns),
)
if err != nil {
panic(fmt.Errorf("数据库链接错误:%s", err.Error()))
}
return r.mainConn
}
// Close 关闭数据库链接
func (r *PostgresPool) Close() error {
if r.mainConn != nil {
db, err := r.mainConn.DB()
if err != nil {
return fmt.Errorf("关闭数据库链接失败:获取数据库链接失败 %s", err.Error())
}
err = db.Close()
if err != nil {
return fmt.Errorf("关闭数据库连接失败 %s", err.Error())
}
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jericho-yu/util.git
git@gitee.com:jericho-yu/util.git
jericho-yu
util
util
v2.17.1

搜索帮助