Skip to content

Gin 实战 6:接入数据库与 GORM

后台系统的数据最终要落到 MySQL。本章接入 GORM,完成数据库配置、连接池和全局 *gorm.DB 初始化。

1. 安装依赖

bash
go get gorm.io/gorm
go get gorm.io/driver/mysql

2. 补充数据库配置

configs/dev.yaml

yaml
database:
  host: 127.0.0.1
  port: 3306
  username: root
  password: root
  dbname: youlai_admin
  charset: utf8mb4
  parseTime: true
  loc: Local
  maxIdleConns: 10
  maxOpenConns: 100
  connMaxLifetime: 3600

3. 生成 DSN

创建 internal/common/database/config.go

go
package database

import "fmt"

type Config struct {
    // 基础连接信息,对应 MySQL 地址、端口和账号密码。
    Host            string `mapstructure:"host"`
    Port            int    `mapstructure:"port"`
    Username        string `mapstructure:"username"`
    Password        string `mapstructure:"password"`
    DBName          string `mapstructure:"dbname"`

    // DSN 参数。parseTime=true 可以让 MySQL 时间字段正确映射到 time.Time。
    Charset         string `mapstructure:"charset"`
    ParseTime       bool   `mapstructure:"parseTime"`
    Loc             string `mapstructure:"loc"`

    // 连接池参数,避免每次请求都新建数据库连接。
    MaxIdleConns    int    `mapstructure:"maxIdleConns"`
    MaxOpenConns    int    `mapstructure:"maxOpenConns"`
    ConnMaxLifetime int    `mapstructure:"connMaxLifetime"`
}

// DSN 把结构化配置拼成 MySQL Driver 需要的连接字符串。
func (c Config) DSN() string {
    return fmt.Sprintf(
        "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%t&loc=%s",
        c.Username, c.Password, c.Host, c.Port, c.DBName,
        c.Charset, c.ParseTime, c.Loc,
    )
}

把第二章的 Config.Database 类型替换为 database.Config

4. 初始化 GORM

创建 internal/common/database/database.go

go
package database

import (
    "time"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

// DB 保存全局数据库连接。
// 简化阶段先全局使用,后面 Repository 会通过它访问数据库。
var DB *gorm.DB

func Init(cfg Config) error {
    // 使用配置生成 DSN,并创建 GORM 连接。
    db, err := gorm.Open(mysql.Open(cfg.DSN()), &gorm.Config{})
    if err != nil {
        return err
    }

    // GORM 底层仍然使用 database/sql,这里取出底层连接池做参数设置。
    sqlDB, err := db.DB()
    if err != nil {
        return err
    }

    // 最大空闲连接数:控制空闲连接池大小。
    sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)

    // 最大打开连接数:控制应用最多占用多少数据库连接。
    sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)

    // 单个连接最大复用时间,避免长连接一直不释放。
    sqlDB.SetConnMaxLifetime(time.Duration(cfg.ConnMaxLifetime) * time.Second)

    // 初始化成功后赋值给全局 DB,供 Repository 使用。
    DB = db
    return nil
}

5. main.go 接入数据库

go
// 数据库初始化应放在路由注册之前。
// 如果数据库不可用,服务不应该继续启动。
if err := database.Init(config.Cfg.Database); err != nil {
    log.Fatalf("数据库初始化失败: %v", err)
}

启动时如果数据库连不上,服务直接失败。这样比接口运行时才报错更早、更清楚。下一章基于 GORM 写用户 CRUD。

基于 MIT 许可发布 · 如需部署协助或二开定制,请查看 支持与合作