66package common
77
88import (
9+ "database/sql"
910 "fmt"
1011 "gotribe-admin/config"
1112 "gotribe-admin/internal/pkg/model/migrate"
@@ -23,95 +24,138 @@ import (
2324// 全局数据库变量
2425var DB * gorm.DB
2526
26- // 初始化数据库
27- func InitDatabase () {
28- var dsn string
29- var showDsn string
27+ // getGormConfig 获取 GORM 通用配置
28+ func getGormConfig () * gorm.Config {
29+ return & gorm.Config {
30+ // 禁用外键(指定外键时不会在数据库创建真实的外键约束)
31+ DisableForeignKeyConstraintWhenMigrating : true ,
32+ // 使用单数表名
33+ NamingStrategy : schema.NamingStrategy {
34+ SingularTable : true ,
35+ },
36+ }
37+ }
3038
31- if config .Conf .Database .Type == "postgres" {
32- dsn = fmt .Sprintf ("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s %s" ,
33- config .Conf .Database .Host ,
34- config .Conf .Database .Username ,
35- config .Conf .Database .Password ,
36- config .Conf .Database .Database ,
37- config .Conf .Database .Port ,
38- config .Conf .Database .SSLMode ,
39- config .Conf .Database .Query ,
40- )
41- showDsn = fmt .Sprintf ("host=%s user=%s password=****** dbname=%s port=%d sslmode=%s %s" ,
42- config .Conf .Database .Host ,
43- config .Conf .Database .Username ,
44- config .Conf .Database .Database ,
45- config .Conf .Database .Port ,
46- config .Conf .Database .SSLMode ,
47- config .Conf .Database .Query ,
48- )
49- } else {
50- // MySQL 连接字符串
51- dsn = fmt .Sprintf ("%s:%s@tcp(%s:%d)/%s?charset=%s&collation=%s&%s" ,
52- config .Conf .Database .Username ,
53- config .Conf .Database .Password ,
54- config .Conf .Database .Host ,
55- config .Conf .Database .Port ,
56- config .Conf .Database .Database ,
57- config .Conf .Database .Charset ,
58- config .Conf .Database .Collation ,
59- config .Conf .Database .Query ,
60- )
61- showDsn = fmt .Sprintf (
62- "%s:******@tcp(%s:%d)/%s?charset=%s&collation=%s&%s" ,
63- config .Conf .Database .Username ,
64- config .Conf .Database .Host ,
65- config .Conf .Database .Port ,
66- config .Conf .Database .Database ,
67- config .Conf .Database .Charset ,
68- config .Conf .Database .Collation ,
69- config .Conf .Database .Query ,
70- )
39+ // buildPostgresDSN 构建 PostgreSQL 连接字符串
40+ func buildPostgresDSN (maskPassword bool ) string {
41+ db := config .Conf .Database
42+
43+ // 处理 SSLMode 默认值
44+ sslMode := db .SSLMode
45+ if sslMode == "" {
46+ sslMode = "disable"
47+ }
48+
49+ // 处理 Query 参数,如果为空则不添加
50+ queryPart := ""
51+ if db .Query != "" {
52+ queryPart = " " + db .Query
53+ }
54+
55+ password := db .Password
56+ if maskPassword {
57+ password = "******"
58+ }
59+
60+ return fmt .Sprintf ("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s%s" ,
61+ db .Host , db .Username , password , db .Database , db .Port , sslMode , queryPart )
62+ }
63+
64+ // buildMySQLDSN 构建 MySQL 连接字符串
65+ func buildMySQLDSN (maskPassword bool ) string {
66+ db := config .Conf .Database
67+
68+ // 处理 Query 参数,如果为空则不添加 & 前缀
69+ queryPart := ""
70+ if db .Query != "" {
71+ queryPart = "&" + db .Query
72+ }
73+
74+ password := db .Password
75+ if maskPassword {
76+ password = "******"
7177 }
7278
73- var db * gorm.DB
74- var err error
79+ return fmt .Sprintf ("%s:%s@tcp(%s:%d)/%s?charset=%s&collation=%s%s" ,
80+ db .Username , password , db .Host , db .Port , db .Database ,
81+ db .Charset , db .Collation , queryPart )
82+ }
83+
84+ // setupDatabaseLogger 配置数据库日志
85+ func setupDatabaseLogger (db * gorm.DB ) {
86+ if ! config .Conf .Database .LogMode {
87+ return
88+ }
89+
90+ newLogger := logger .New (
91+ log .New (os .Stdout , "\r \n " , log .LstdFlags ),
92+ logger.Config {
93+ SlowThreshold : time .Second ,
94+ LogLevel : logger .Info ,
95+ Colorful : true ,
96+ },
97+ )
98+ db .Debug ()
99+ db .Logger = newLogger
100+ }
101+
102+ // openDatabase 打开数据库连接
103+ func openDatabase (dsn string ) (* gorm.DB , error ) {
104+ dbType := config .Conf .Database .Type
105+ gormConfig := getGormConfig ()
106+
107+ if dbType == "postgres" {
108+ return gorm .Open (postgres .Open (dsn ), gormConfig )
109+ }
110+ // 默认使用 MySQL
111+ return gorm .Open (mysql .Open (dsn ), gormConfig )
112+ }
75113
114+ // 初始化数据库
115+ func InitDatabase () {
116+ var dsn , showDsn string
117+
118+ // 根据数据库类型构建连接字符串
76119 if config .Conf .Database .Type == "postgres" {
77- db , err = gorm .Open (postgres .Open (dsn ), & gorm.Config {
78- // 禁用外键(指定外键时不会在数据库创建真实的外键约束)
79- DisableForeignKeyConstraintWhenMigrating : true ,
80- // 使用单数表名
81- NamingStrategy : schema.NamingStrategy {
82- SingularTable : true ,
83- },
84- })
120+ dsn = buildPostgresDSN (false )
121+ showDsn = buildPostgresDSN (true )
85122 } else {
86- db , err = gorm .Open (mysql .Open (dsn ), & gorm.Config {
87- // 禁用外键(指定外键时不会在数据库创建真实的外键约束)
88- DisableForeignKeyConstraintWhenMigrating : true ,
89- // 使用单数表名
90- NamingStrategy : schema.NamingStrategy {
91- SingularTable : true ,
92- },
93- })
123+ dsn = buildMySQLDSN (false )
124+ showDsn = buildMySQLDSN (true )
94125 }
126+
127+ // 打开数据库连接
128+ db , err := openDatabase (dsn )
95129 if err != nil {
96130 Log .Panicf ("初始化数据库异常: %v" , err )
97131 panic (fmt .Errorf ("初始化数据库异常: %v" , err ))
98132 }
99133
100- // 开启数据库日志
101- if config .Conf .Database .LogMode {
102- newLogger := logger .New (
103- log .New (os .Stdout , "\r \n " , log .LstdFlags ),
104- logger.Config {
105- SlowThreshold : time .Second ,
106- LogLevel : logger .Info ,
107- Colorful : true ,
108- },
109- )
110- db .Debug ()
111- db .Logger = newLogger
134+ // 配置数据库日志
135+ setupDatabaseLogger (db )
136+
137+ // 配置连接池参数,避免连接频繁关闭和重连导致的日志输出
138+ var sqlDB * sql.DB
139+ sqlDB , err = db .DB ()
140+ if err != nil {
141+ Log .Panicf ("获取数据库连接失败: %v" , err )
142+ panic (fmt .Errorf ("获取数据库连接失败: %v" , err ))
112143 }
144+
145+ // 设置连接池参数
146+ // SetMaxOpenConns: 设置打开数据库连接的最大数量
147+ sqlDB .SetMaxOpenConns (100 )
148+ // SetMaxIdleConns: 设置空闲连接池中连接的最大数量
149+ sqlDB .SetMaxIdleConns (10 )
150+ // SetConnMaxLifetime: 设置连接可复用的最大时间(应该小于 MySQL 的 wait_timeout)
151+ // MySQL 默认 wait_timeout 是 8 小时,这里设置为 7 小时,避免连接被 MySQL 主动关闭
152+ sqlDB .SetConnMaxLifetime (7 * time .Hour )
153+ // SetConnMaxIdleTime: 设置连接的最大空闲时间,超过此时间的空闲连接会被关闭
154+ sqlDB .SetConnMaxIdleTime (1 * time .Hour )
155+
113156 // 全局DB赋值
114157 DB = db
158+
115159 // 自动迁移表结构
116160 if config .Conf .System .EnableMigrate {
117161 migrate .DBAutoMigrate (DB )
0 commit comments