Skip to content

multi db

为了封装一个数据库支持的系统,您可以通过读取配置文件来决定使用哪种数据库(例如 MySQL、PostgreSQL、SQLite 等),然后根据配置选择适当的数据库驱动进行连接。我们可以使用 Go 的 viper 库来加载配置文件,并通过 gorm 来实现数据库的连接和操作。

步骤

  1. 安装依赖
    • gorm: Go ORM 库。
    • viper: 配置文件读取库。
bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u gorm.io/driver/postgres
go get -u gorm.io/driver/sqlite
go get -u github.com/spf13/viper
  1. 创建配置文件: 假设我们使用 YAML 格式的配置文件,config.yaml 用于指定数据库类型和连接信息。

    yaml
    database:
      type: mysql  # 选择数据库类型: mysql, postgres, sqlite
      mysql:
        dsn: "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
      postgres:
        dsn: "user=gorm password=gorm dbname=gorm port=5432 sslmode=disable TimeZone=Asia/Shanghai"
      sqlite:
        dsn: "test.db"
  2. 创建数据库封装层: 我们需要创建一个封装层,通过读取配置文件动态地选择数据库类型,并连接到对应的数据库。

代码实现

go
package main

import (
	"fmt"
	"log"
	"gorm.io/driver/mysql"
	"gorm.io/driver/postgres"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"github.com/spf13/viper"
)

// 定义数据库配置结构体
type DatabaseConfig struct {
	Type   string `mapstructure:"type"`
	MySQL  MySQLConfig
	Postgres PostgreSQLConfig
	SQLite SQLiteConfig
}

type MySQLConfig struct {
	DSN string `mapstructure:"dsn"`
}

type PostgreSQLConfig struct {
	DSN string `mapstructure:"dsn"`
}

type SQLiteConfig struct {
	DSN string `mapstructure:"dsn"`
}

// 封装数据库连接函数
func InitDatabase(config DatabaseConfig) (*gorm.DB, error) {
	var db *gorm.DB
	var err error

	// 根据配置选择数据库驱动
	switch config.Type {
	case "mysql":
		db, err = gorm.Open(mysql.Open(config.MySQL.DSN), &gorm.Config{})
		if err != nil {
			return nil, fmt.Errorf("failed to connect to MySQL: %w", err)
		}
	case "postgres":
		db, err = gorm.Open(postgres.Open(config.Postgres.DSN), &gorm.Config{})
		if err != nil {
			return nil, fmt.Errorf("failed to connect to PostgreSQL: %w", err)
		}
	case "sqlite":
		db, err = gorm.Open(sqlite.Open(config.SQLite.DSN), &gorm.Config{})
		if err != nil {
			return nil, fmt.Errorf("failed to connect to SQLite: %w", err)
		}
	default:
		return nil, fmt.Errorf("unsupported database type: %s", config.Type)
	}

	// 连接成功后返回数据库对象
	return db, nil
}

// 加载配置文件
func loadConfig() (DatabaseConfig, error) {
	var config DatabaseConfig
	viper.SetConfigName("config")  // 配置文件名 (不带扩展名)
	viper.AddConfigPath(".")       // 配置文件路径
	viper.SetConfigType("yaml")    // 配置文件类型

	if err := viper.ReadInConfig(); err != nil {
		return config, fmt.Errorf("error reading config file, %s", err)
	}

	// 读取配置文件到结构体
	err := viper.Unmarshal(&config)
	if err != nil {
		return config, fmt.Errorf("unable to decode into struct, %v", err)
	}

	return config, nil
}

func main() {
	// 读取配置
	config, err := loadConfig()
	if err != nil {
		log.Fatalf("Error loading config: %v", err)
	}

	// 初始化数据库连接
	db, err := InitDatabase(config)
	if err != nil {
		log.Fatalf("Error initializing database: %v", err)
	}

	// 如果连接成功,打印数据库连接成功消息
	fmt.Println("Connected to database successfully!")

	// 在这里进行数据库操作,例如自动迁移、数据查询等
	// db.AutoMigrate(&YourModel{})
}

4. 配置文件 config.yaml

创建一个 config.yaml 配置文件,指定要连接的数据库及其连接字符串。

yaml
database:
  type: mysql  # mysql, postgres, sqlite
  mysql:
    dsn: "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
  postgres:
    dsn: "user=gorm password=gorm dbname=gorm port=5432 sslmode=disable TimeZone=Asia/Shanghai"
  sqlite:
    dsn: "test.db"

5. 代码解释

  • loadConfig:使用 viper 加载配置文件并将其解码到 DatabaseConfig 结构体中。配置文件支持三种数据库类型(MySQL、PostgreSQL 和 SQLite),并且每种类型的配置都放在不同的字段中。

  • InitDatabase:根据从配置文件读取的数据库类型选择对应的数据库驱动进行连接。通过 gorm.Open() 来初始化数据库连接并返回 *gorm.DB 对象。

  • main 函数:加载配置,调用 InitDatabase 连接到数据库,并打印连接成功消息。您可以在此后执行数据库操作(例如表迁移、查询等)。

6. 运行示例

  1. 创建配置文件 config.yaml,并设置好对应的数据库连接信息。
  2. 运行 Go 代码:
bash
go run main.go

7. 数据库驱动支持的操作

InitDatabase 函数中,如果数据库连接成功,您就可以通过 db 对象进行任何支持的数据库操作,如:

  • 自动迁移 (db.AutoMigrate(...))
  • 插入数据 (db.Create(...))
  • 查询数据 (db.First(...))
  • 更新数据 (db.Save(...))
  • 删除数据 (db.Delete(...))

8. 总结

通过上面的封装,您可以实现一个通用的数据库支持系统,能够根据配置文件动态选择并连接不同类型的数据库。这种方法使得您可以灵活地在不同的数据库之间切换,特别适合需要支持多数据库的应用场景。