• 在 Go 中管理多个数据库连接


    简介

    作为软件工程师,经常会遇到应用程序需要与多个数据库协同工作的情况,而每个数据库都有其独特的要求和配置。在遵守最佳编码实践的同时,有效地处理这些不同的数据库连接对于构建健壮且易于维护的应用程序至关重要。

    挑战:多个数据库连接

    在软件开发过程中,使用 MySQL、PostgreSQL 或其他数据库是很常见的。由于配置和要求不同,管理这些连接可能具有挑战性。为了有效应对这一挑战,我们将提供一个分步指南和一个实用示例。

    步骤 1:数据库配置

    首先定义一个 DBConfig 结构,用于保存每个数据库的配置详细信息。这些配置包括数据库类型、用户凭证、主机、端口等关键参数。

    // DBConfig 表示数据库的配置。
    type DBConfig struct {
     IdentificationName string // IdentificationName 用于获取特定的数据库连接。
     DB                 string   
     User               string   
     Password           string   `json:"_"` 
     Host               string   
     Port               string  
     Type               string   // Type of the database ("mysql", "postgres", "mssql", etc.).
     SSLMode            string   
     TimeZone           string   
     dialector          gorm.Dialector 
    }
    
    // Connect 根据提供的配置建立数据库连接。
    func (config *DBConfig) Connect() (DBConnection, error) {
     db, err := gorm.Open(config.dialector, &gorm.Config{})
     return db, err
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    步骤 2:数据库连接接口

    type DBConnection *gorm.DB
    
    type DatabaseConnection interface {
        Connect() (DBConnection, error)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    步骤 3:实施数据库连接

    实现两种类型的数据库连接:MySQL 和 PostgreSQL。每种连接类型都有自己的 Connect 方法,可根据提供的配置配置数据库连接参数,并返回一个 GORM DB 实例。

    // MySQLConnection 实现了 MySQL 的 DatabaseConnection。
    type MySQLConnection struct {
     Config *DBConfig
    }
    
    // Connect 连接到 MySQL 数据库,并返回一个 GORM DB 实例。
    func (m *MySQLConnection) Connect() (DBConnection, error) {
     dsn := "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=%s"
     m.Config.dialector = mysql.Open(fmt.Sprintf(dsn, m.Config.User, m.Config.Password, m.Config.Host, m.Config.Port, m.Config.DB, m.Config.TimeZone))
     db, err := m.Config.Connect()
     return db, err
    }
    
    // PostgresConnection 实现了 PostgreSQL 的 DatabaseConnection。
    type PostgresConnection struct {
     Config *DBConfig
    }
    
    // Connect 连接 PostgreSQL 数据库并返回 GORM DB 实例。
    func (p *PostgresConnection) Connect() (DBConnection, error) {
     dsn := "host=%s user=%s password=%s dbname=%s port=%s sslmode=%s TimeZone=%s"
     p.Config.dialector = postgres.Open(fmt.Sprintf(dsn, p.Config.Host, p.Config.User, p.Config.Password, p.Config.DB, p.Config.Port, p.Config.SSLMode, p.Config.TimeZone))
     db, err := p.Config.Connect()
     return db, err
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    步骤 4:创建和管理数据库连接

    创建一个 NewConnection 函数,根据给定配置生成一个新的数据库连接。该函数还能自动执行数据库迁移,以确保数据库表结构是最新的。

    // NewConnection 根据给定的配置创建新的数据库连接。
    func (config *DBConfig) NewConnection() (DBConnection, error) {
     var dbConnection DatabaseConnection
     switch config.Type {
     case "mysql":
      dbConnection = &MySQLConnection{Config: config}
     case "postgres":
      dbConnection = &PostgresConnection{Config: config}
     default:
      return nil, fmt.Errorf("Unsupported database type: %s", config.Type)
     }
    
     // 创建新连接
     con, err := dbConnection.Connect()
     if err != nil {
      return nil, err
     }
    
     // 自动迁移表结构
     err = con.Statement.AutoMigrate(&dto.User{})
     if err != nil {
      return nil, err
     }
    
     return con, nil
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    步骤 5:使用数据库连接

    在 main 函数中,初始化并使用数据库连接。通过标识名访问特定连接,并执行必要的数据库操作。

    func init() {
     // 在程序启动时初始化数据库连接。
     configs.InitDBConnections()
    }
    
    func main() {
     users := []dto.User{
      {
       UserName: "user1",
       Password: "test1",
      },
      {
       UserName: "user2",
       Password: "test2",
      },
     }
    
     // 使用指定的连接名称创建新的用户资源库
     repo := repo.NewUserRepo("TEST_POSTGRES_CON")
    
     err := repo.Save(users...)
     if err != nil {
      return
     }
    
     users, err = repo.FindAll()
     if err != nil {
      return
     }
    
     for _, user := range users {
      fmt.Printf("%+v\n", user)
     }
    
     // 设置侦听操作系统信号的通道(例如 Ctrl+C)
     c := make(chan os.Signal, 1)
     signal.Notify(c, os.Interrupt, syscall.SIGTERM)
     // 等待信号(如 Ctrl+C),优雅地退出程序
     <-c
    
     // 程序终止时关闭数据库连接。
     defer configs.CloseDBConnections()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    结论

    在 Go 中管理多个数据库连接是软件开发中常见的难题。按照本文概述的步骤并利用所提供的示例代码,可以有效地处理各种数据库类型,同时保持代码的整洁和可维护性。
    有了这种方法,你就可以在 Go 项目中自信地使用多个数据库,确保随着应用程序的增长而具有可扩展性和可维护性。简洁、可维护的代码对任何软件项目的成功都至关重要,而掌握多个数据库连接的管理则是软件工程师的一项宝贵技能。

  • 相关阅读:
    2022年湖北劳务资质如何办理?劳务资质不分等级
    OpenMMLab MMYOLO目标检测环境搭建(一)
    分布式消息队列RocketMQ概念详解
    ubuntu常用命令
    Jenkins的Pipeline概念
    使用163开源镜像升级Centos
    【Golang开发面经】知乎(两轮技术面)
    【无标题】
    优雅处理Golang中的异常
    MySQL性能调优,必须掌握这一个工具!!!(1分钟系列)
  • 原文地址:https://blog.csdn.net/ldxxxxll/article/details/136270468