golang-yitisheng-server/server/config/database.go

112 lines
2.6 KiB
Go

// Package config 配置包,负责应用程序的配置管理
package config
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// DB 全局数据库连接实例
var DB *gorm.DB
// getLogWriter 获取日志输出目标
func getLogWriter() io.Writer {
logConfig := AppConfig.Log
if logConfig.Dir == "" {
return os.Stdout
}
if err := os.MkdirAll(logConfig.Dir, 0755); err != nil {
fmt.Printf("创建日志目录失败: %v\n", err)
return os.Stdout
}
filename := fmt.Sprintf("sql-%s.log", time.Now().Format("2006-01-02"))
logPath := filepath.Join(logConfig.Dir, filename)
file, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Printf("打开SQL日志文件失败: %v\n", err)
return os.Stdout
}
if logConfig.Console {
return io.MultiWriter(file, os.Stdout)
}
return file
}
// InitDB 初始化数据库连接
func InitDB() {
dbConfig := AppConfig.Database
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Asia%%2FShanghai",
dbConfig.Username,
dbConfig.Password,
dbConfig.Host,
dbConfig.Port,
dbConfig.Database,
dbConfig.Charset,
)
var gormConfig *gorm.Config
if dbConfig.LogMode {
writer := getLogWriter()
newLogger := logger.New(
log.New(writer, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // Slow SQL threshold
LogLevel: logger.Info, // Log level
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
ParameterizedQueries: false, // 包含参数在 SQL 日志中
Colorful: false, // 写入文件时建议关闭彩色打印,否则会有乱码
},
)
gormConfig = &gorm.Config{
Logger: newLogger,
}
} else {
gormConfig = &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
}
}
var err error
DB, err = gorm.Open(mysql.Open(dsn), gormConfig)
if err != nil {
log.Fatal("数据库连接失败:", err)
}
// 获取底层 sql.DB 以配置连接池
sqlDB, err := DB.DB()
if err != nil {
log.Fatal("获取数据库实例失败:", err)
}
// 连接池配置
sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConns)
sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConns)
sqlDB.SetConnMaxLifetime(time.Duration(dbConfig.ConnMaxLifetime) * time.Hour)
fmt.Println("数据库连接成功")
}
// CloseDB 关闭数据库连接
// 在程序退出时调用,释放所有连接
func CloseDB() {
if DB != nil {
sqlDB, err := DB.DB()
if err == nil {
sqlDB.Close()
fmt.Println("数据库连接已关闭")
}
}
}