如何在Golang Revel中动态获取app.conf数据库配置实现多库迁移
在Revel框架中动态获取多数据库配置并批量迁移
实现思路
Revel的Config接口提供了Keys()方法可获取配置文件中所有键,我们通过筛选前缀为db.dbname的键,动态收集所有数据库名称,再结合通用数据库配置构建连接,最后批量执行迁移。
具体实现步骤及代码
筛选所有数据库名称配置
遍历app.conf的所有配置键,提取出所有以db.dbname开头的项,区分默认数据库(db.dbname)和其他数据库(db.dbname.xxx)。批量建立数据库连接
结合通用配置(驱动、用户名、密码等)为每个数据库构建DSN,创建GORM连接实例。执行批量迁移
对每个连接好的数据库实例,执行AutoMigrate操作。
package main import ( "fmt" "strings" "github.com/revel/revel" "gorm.io/driver/mysql" "gorm.io/gorm" ) // 全局存储多数据库连接,方便业务代码调用 var globalDBs = make(map[string]*gorm.DB) func init() { // 在Revel启动时初始化多数据库 revel.OnAppStart(func() { err := initMultiDBs() if err != nil { revel.Fatalf("初始化数据库失败: %v", err) } }) } func initMultiDBs() error { // 获取通用数据库配置 driver := revel.Config.StringDefault("db.driver", "mysql") username := revel.Config.StringDefault("db.username", "root") password := revel.Config.StringDefault("db.password", "") charset := revel.Config.StringDefault("db.charset", "utf8") parseTime := revel.Config.BoolDefault("db.parseTime", true) loc := revel.Config.StringDefault("db.loc", "") autoMigrate := revel.Config.BoolDefault("db.automigrate", false) // 获取配置文件中所有键 allKeys := revel.Config.Keys() dbConfigs := make(map[string]string) // 筛选出所有db.dbname相关配置 for _, key := range allKeys { if strings.HasPrefix(key, "db.dbname") { var dbAlias string if key == "db.dbname" { dbAlias = "default" } else { // 提取数据库别名,如db.dbname.otherdatabase -> otherdatabase dbAlias = strings.TrimPrefix(key, "db.dbname.") } dbName := revel.Config.StringDefault(key, "") if dbName != "" { dbConfigs[dbAlias] = dbName } } } // 遍历配置,建立连接并迁移 for alias, dbName := range dbConfigs { // 构建MySQL DSN,使用其他驱动时需调整格式 dsn := fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/%s?charset=%s&parseTime=%t&loc=%s", username, password, dbName, charset, parseTime, loc) // 建立数据库连接 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { return fmt.Errorf("连接%s数据库失败: %v", alias, err) } // 执行自动迁移 if autoMigrate { // 替换为你的业务模型,若不同数据库需迁移不同模型,可根据alias判断 err = db.AutoMigrate( &models.User{}, &models.Order{}, // 其他模型... ) if err != nil { return fmt.Errorf("迁移%s数据库失败: %v", alias, err) } } // 存储连接实例 globalDBs[alias] = db revel.Infof("成功初始化%s数据库: %s", alias, dbName) } return nil }
扩展说明
- 若不同数据库需要独立的连接参数(如主机、端口),可仿照
db.dbname.xxx的格式配置db.host.xxx、db.port.xxx,在构建DSN时动态获取对应值。 - 业务代码中可通过
globalDBs["default"]或globalDBs["otherdatabase"]调用对应数据库的连接实例。 - 迁移时如果需要针对不同数据库执行不同的模型迁移,可通过判断
alias值区分处理。
内容的提问来源于stack exchange,提问作者Michael Halim
相关产品推荐
相关产品推荐

