package db import ( "apiServer_service/utils/logger" "fmt" "os" "sync" "time" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" ) var ( DB *gorm.DB once sync.Once ) func ConnectDatabase() { once.Do(func() { dbType := os.Getenv("DB_TYPE") dbUser := os.Getenv("DB_USER") dbPassword := os.Getenv("DB_PASSWORD") dbName := os.Getenv("DB_NAME") dbHost := os.Getenv("DB_HOST") dbPort := os.Getenv("DB_PORT") if dbType == "" { logger.Warn("Database", "DB_TYPE 未配置,跳过数据库连接") return } var dialector gorm.Dialector switch dbType { case "mysql": dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPassword, dbHost, dbPort, dbName) dialector = mysql.Open(dsn) case "postgres": dbSchema := os.Getenv("DB_SCHEMA") if dbSchema == "" { dbSchema = "public" } dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai search_path=%s", dbHost, dbUser, dbPassword, dbName, dbPort, dbSchema) dialector = postgres.Open(dsn) default: logger.Fatal("Database", fmt.Sprintf("不支持的 DB_TYPE: %s(仅支持 mysql / postgres)", dbType)) return } conn, err := gorm.Open(dialector, &gorm.Config{}) if err != nil { logger.Fatal("Database", "连接失败: ", err) return } sqlDB, err := conn.DB() if err != nil { logger.Fatal("Database", "获取底层连接池失败: ", err) return } sqlDB.SetMaxOpenConns(50) sqlDB.SetMaxIdleConns(10) sqlDB.SetConnMaxLifetime(30 * time.Minute) sqlDB.SetConnMaxIdleTime(10 * time.Minute) DB = conn logger.Info("Database", fmt.Sprintf("连接成功 (%s)", dbType)) }) } func GetDB() *gorm.DB { if DB == nil { ConnectDatabase() } return DB } // Migrate 自动迁移所有模型,新增模型在此注册 func Migrate() { if DB == nil { logger.Warn("Database", "数据库未连接,跳过迁移") return } models := []interface{}{ &HostGroup{}, } for _, model := range models { if err := DB.AutoMigrate(model); err != nil { logger.Error("Database", fmt.Sprintf("迁移 %T 失败: %v", model, err)) } else { logger.Info("Database", fmt.Sprintf("迁移 %T 完成", model)) } } }