Files
go-omni/database/mysql

官方 MySQL 适配器

本包可选,使用 database/sql 和 go-sql-driver/mysql,复用框架的唯一连接池、Ping、事务与健康检查。不自动建库/迁移、不重试写操作,也不强制某个 MySQL 版本或业务表。

项目使用 GORM 时,在 svc.Init 中调用 gormx.MySQL 即可复用这个池、TLS 和清理流程。

生成项目选择 --database mysql 即接入:

go-omni new --database mysql --module example.com/billing ./billing

etc/config.yaml 使用结构化配置;需要环境变量时在字段值明确写引用,固定值不被覆盖:

database:
  host: db.example.com
  port: 3306
  user: app
  password: "${DB_PASSWORD}"
  database: billing
  parseTime: true
  location: UTC
  charset: utf8mb4
  collation: utf8mb4_bin
  connectTimeout: 5s
  readTimeout: 5s
  writeTimeout: 5s
  tls:
    mode: required
    caFile: /etc/certs/database-ca.pem
    serverName: db.example.com
  pool:
    maxOpenConns: 20
    maxIdleConns: 5
    connMaxLifetime: 30m
    connMaxIdleTime: 5m
    pingTimeout: 5s

示例通过文件里的 ${DB_PASSWORD} 读取密码;HOST、PORT、TLS 和池参数同样按需在文件写引用,不自动扫描变量、不使用 env 标签。新生成服务使用结构化连接参数;独立迁移 CLI 的显式 DSN 参数及 Open/OpenConnector 接口保留。

默认启用 TLS 并校验系统信任链与主机名;私有 CA 用 caFile,双向 TLS 额外设置 certFile/keyFile。只有明确设置 tls.mode: disabled 才使用明文。Unix socket 用 socket,若在 socket 上使用 TLS,必须提供 serverName。不会注册全局 TLS 配置或全局驱动 Logger。

手写入口:

cfg := mysqladapter.DefaultConfig()
// 从项目配置覆盖 cfg;不要打印含密码的完整配置。
db, err := mysqladapter.Open(ctx, cfg, mysqladapter.WithLogger(logger))
if err != nil { return err }
defer db.Close()
// db.DB 是标准 *sql.DB;也可用框架 Health、InTx 等方法。

生成项目的 internal/svc/databaseOptions.go 是保留的项目扩展位置:

func (c *ServiceContext) DatabaseOptions() []mysqladapter.Option {
    return []mysqladapter.Option{
        mysqladapter.WithStartupCheck(func(ctx context.Context, db *database.DB) error {
            return checkProjectSchema(ctx, db)
        }),
    }
}

检查在 Ping 后运行,共享启动时限;失败或 panic 会关闭新连接池。版本/表结构检查放在这些回调中,不放到框架。回调必须响应 context,并且不能自行关闭借用的 db。依赖尚未完成整体初始化时不要把连接池发布到外部。

WithDriverConfig(func(*mysql.Config) error) 支持高级拨号、驱动参数等,配置在回调后克隆;这是项目明确选择的底层扩展。NewConnector 返回标准 driver.Connector,供已有基础设施使用;它不接受启动检查选项。任意驱动仍可用核心 database.OpenConnector。

错误有安全摘要,errors.Is/As 保留 TLS/驱动/项目检查的原因。配置验证不读证书、不连接数据库;Open 才读取证书、创建池并握手。不要自行打印原始配置或展开可能包含内部信息的 driver 字段给用户。

字段级配置错误

Validate 返回独立字段与安全原因,例如 port(1–65535)、readTimeout、pool.maxIdleConns、tls.keyFile。项目调用 config.AtField("database", err) 后,统一加载器补齐 database 前缀、文件、环境名和行列,无需重复写端口/连接池校验。TLS 成对配置会指出缺失的那个字段。连接失败、驱动和证书文件的内部原因仍通过 errors.Is/As 保留,不把凭据放进公开提示。见 配置诊断。