database

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

README

Database Package

基于 GORM 的数据库封装,提供连接管理、事务执行、健康检查以及受控的底层逃逸能力。

定位

database 是资源型 SDK:

  • 主路径是显式实例:New / NewWithOptions
  • 兼容路径是默认实例:Configure / GetClient
  • 单库应用可用默认实例
  • 多库、测试、框架初始化、事务编排优先使用显式实例

特性

  • 支持 MySQL、PostgreSQL、SQLite
  • 配置校验与默认值补齐
  • 连接池与连接重试
  • Connector / Executor / HealthChecker 可替换
  • 支持 Hooks 扩展生命周期
  • 保留 GetDB / Raw / SQLDB 以支持高级 GORM 或驱动原生能力

快速开始

显式实例
package main

import (
	"context"
	"log"

	"github.com/tsopia/go-kit/database"
)

func main() {
	cfg := &database.Config{
		Driver:   "sqlite",
		Database: ":memory:",
		LogLevel: "silent",
	}

	db, err := database.New(cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	if err := db.Ping(); err != nil {
		log.Fatal(err)
	}

	var one int
	if err := db.Query(context.Background(), &one, "SELECT 1"); err != nil {
		log.Fatal(err)
	}
}
默认实例
cfg := &database.Config{
	Driver:   "sqlite",
	Database: ":memory:",
}

if _, err := database.Configure(cfg); err != nil {
	return fmt.Errorf("configure database: %w", err)
}
defer database.CloseDefault()

if err := database.Ping(); err != nil {
	return fmt.Errorf("ping database: %w", err)
}

if err := database.Exec(ctx, "UPDATE users SET last_seen = CURRENT_TIMESTAMP WHERE id = ?", []interface{}{userID}); err != nil {
	return fmt.Errorf("update last_seen: %w", err)
}

说明:

  • 包级 Ping / Exec / Query 是默认实例的便捷包装
  • 若未 Configure 且未传显式实例,将返回 ErrMissingClient
  • 实例方法的调用体验更自然,优先推荐

配置示例

MySQL
cfg := &database.Config{
	Driver:   "mysql",
	Host:     "127.0.0.1",
	Port:     3306,
	Username: "root",
	Password: "password",
	Database: "app",
	LogLevel: "warn",
}
PostgreSQL
cfg := &database.Config{
	Driver:   "postgres",
	Host:     "127.0.0.1",
	Port:     5432,
	Username: "postgres",
	Password: "password",
	Database: "app",
	SSLMode:  "disable",
	LogLevel: "warn",
}
SQLite
cfg := &database.Config{
	Driver:   "sqlite",
	Database: "test.db",
	LogLevel: "silent",
}
重试配置
cfg := &database.Config{
	Driver:             "mysql",
	Host:               "127.0.0.1",
	Port:               3306,
	Username:           "root",
	Password:           "password",
	Database:           "app",
	RetryEnabled:       true,
	RetryMaxAttempts:   5,
	RetryInitialDelay:  500 * time.Millisecond,
	RetryMaxDelay:      10 * time.Second,
	RetryBackoffFactor: 1.5,
	RetryJitterEnabled: true,
}

显式关闭重试:

cfg := &database.Config{
	Driver:          "sqlite",
	Database:        "test.db",
	RetryConfigured: true,
	RetryEnabled:    false,
}

核心 API

构造与默认实例
  • New(config *Config) (*Database, error)
  • NewWithOptions(config *Config, opts ...Option) (*Database, error)
  • Configure(config *Config, opts ...Option) (*Database, error)
  • GetClient() *Database
  • CloseDefault() error
实例方法
  • Exec(ctx context.Context, query string, args ...interface{}) error
  • Query(ctx context.Context, dest interface{}, query string, args ...interface{}) error
  • Tx(ctx context.Context, fn func(tx *gorm.DB) error, opts ...*sql.TxOptions) error
  • BeginTx(ctx context.Context, opts ...*sql.TxOptions) (*gorm.DB, error)
  • Ping() error
  • HealthCheck() error
  • HealthCheckWithContext(ctx context.Context) *HealthStatus
  • GetDB() *gorm.DB
  • Raw() *gorm.DB
  • SQLDB() (*sql.DB, error)
  • Close() error
包级便捷方法
  • Ping(c ...*Database) error
  • Exec(ctx context.Context, query string, args []interface{}, c ...*Database) error
  • Query(ctx context.Context, dest interface{}, query string, args []interface{}, c ...*Database) error

组件化职责

  • Connector:负责建连、重试、命名策略、连接池
  • Executor:负责 Exec / Query / Tx / BeginTx
  • HealthChecker:负责 Ping / HealthCheck / HealthCheckWithContext

可通过以下选项替换默认实现:

  • WithConnector
  • WithExecutor
  • WithHealthChecker
  • WithLogger
  • WithHooks

高级能力

与 gorm/gen 集成
q := query.Use(db.GetDB())

err := db.TransactionWithContext(ctx, func(tx *gorm.DB) error {
	qtx := query.Use(tx).WithContext(ctx)
	_, err := qtx.User.Create(&model.User{Name: "foo"})
	return err
})
使用底层 *sql.DB
sqlDB, err := db.SQLDB()
if err != nil {
	return fmt.Errorf("get sql db: %w", err)
}
defer sqlDB.Close()

测试

GOCACHE=/tmp/go-build go test ./database -v

说明:

  • 某些环境直接执行 go test ./... 可能受仓库已知 sonic 基线问题影响
  • database 无关时,优先使用包级增量测试验证

注意事项

  1. database 管理连接资源,使用完毕后应调用 Close()CloseDefault()
  2. 默认实例适合单库应用;多库场景优先显式实例
  3. 包级 helper 为兼容入口,复杂调用优先实例方法

Documentation

Index

Constants

View Source
const (
	DefaultMaxIdleConns     = 10
	DefaultMaxOpenConns     = 100
	DefaultConnMaxLifetime  = time.Hour
	DefaultConnMaxIdleTime  = 10 * time.Minute
	DefaultSlowThreshold    = time.Second
	DefaultLogLevel         = "silent"
	DefaultCharset          = "utf8mb4"
	DefaultTimezone         = "Local"
	DefaultPostgresSSLMode  = "disable"
	DefaultPostgresTimezone = "UTC"

	// 重试配置默认值
	DefaultRetryMaxAttempts   = 3
	DefaultRetryInitialDelay  = 1 * time.Second
	DefaultRetryMaxDelay      = 30 * time.Second
	DefaultRetryBackoffFactor = 2.0
	DefaultRetryJitterEnabled = true

	MaxRetryAttempts = 100
)

默认配置常量

Variables

View Source
var (
	ErrMissingClient     = errors.New("database: client not configured")
	ErrMissingDriver     = errors.New("数据库驱动不能为空")
	ErrUnsupportedDriver = errors.New("不支持的数据库驱动")
	ErrMissingHost       = errors.New("数据库主机不能为空")
	ErrInvalidPort       = errors.New("数据库端口无效")
	ErrMissingUsername   = errors.New("数据库用户名不能为空")
	ErrMissingDatabase   = errors.New("数据库名不能为空")
	ErrMissingDBPath     = errors.New("SQLite数据库路径不能为空")
	ErrInvalidLogLevel   = errors.New("无效的日志级别")
	ErrInvalidCharset    = errors.New("无效的字符集")
	ErrInvalidSSLMode    = errors.New("无效的SSL模式")
	ErrInvalidConnPool   = errors.New("连接池配置无效")
	ErrInvalidTimeout    = errors.New("超时配置无效")
	ErrConnectionFailed  = errors.New("数据库连接失败")
	ErrTransactionFailed = errors.New("事务执行失败")
	ErrQueryFailed       = errors.New("查询执行失败")
	ErrMigrationFailed   = errors.New("数据库迁移失败")
)

预定义错误

Functions

func CloseDefault added in v1.6.0

func CloseDefault() error

CloseDefault 关闭默认客户端并清空引用。

func Exec added in v1.6.0

func Exec(ctx context.Context, query string, args []interface{}, c ...*Database) error

Exec 使用默认客户端或显式覆盖客户端执行写操作。

func IsConnectionError

func IsConnectionError(err error) bool

IsConnectionError 检查是否为连接错误

func IsValidLogLevel

func IsValidLogLevel(level string) bool

IsValidLogLevel 验证日志级别是否有效

func IsValidationError

func IsValidationError(err error) bool

IsValidationError 检查是否为验证错误

func NewGormLogger

func NewGormLogger(l SimpleLogger, logLevel string) logger.Interface

NewGormLogger 构造函数

  • l: 你的 zap / logrus / zerolog ... 实例
  • level: GORM 日志级别,不想打印 SQL 就传 logger.Silent

func Ping added in v1.6.0

func Ping(c ...*Database) error

Ping 使用默认客户端或显式覆盖客户端进行连通性检测。

func Query added in v1.6.0

func Query(ctx context.Context, dest interface{}, query string, args []interface{}, c ...*Database) error

Query 使用默认客户端或显式覆盖客户端执行查询。

Types

type Config

type Config struct {
	// 基础连接配置
	Driver   string `mapstructure:"driver" json:"driver" yaml:"driver"`
	Host     string `mapstructure:"host" json:"host" yaml:"host"`
	Port     int    `mapstructure:"port" json:"port" yaml:"port"`
	Username string `mapstructure:"username" json:"username" yaml:"username"`
	Password string `mapstructure:"password" json:"password" yaml:"password"`
	Database string `mapstructure:"database" json:"database" yaml:"database"`
	Charset  string `mapstructure:"charset" json:"charset" yaml:"charset"`
	SSLMode  string `mapstructure:"ssl_mode" json:"ssl_mode" yaml:"ssl_mode"`
	Timezone string `mapstructure:"timezone" json:"timezone" yaml:"timezone"`

	// 连接池配置
	MaxIdleConns    int           `mapstructure:"max_idle_conns" json:"max_idle_conns" yaml:"max_idle_conns"`
	MaxOpenConns    int           `mapstructure:"max_open_conns" json:"max_open_conns" yaml:"max_open_conns"`
	ConnMaxLifetime time.Duration `mapstructure:"conn_max_lifetime" json:"conn_max_lifetime" yaml:"conn_max_lifetime"`
	ConnMaxIdleTime time.Duration `mapstructure:"conn_max_idle_time" json:"conn_max_idle_time" yaml:"conn_max_idle_time"`

	// GORM日志配置
	CustomLogger              logger.Interface `mapstructure:"-" json:"-" yaml:"-"`
	LogLevel                  string           `mapstructure:"log_level" json:"log_level" yaml:"log_level"`
	SlowThreshold             time.Duration    `mapstructure:"slow_threshold" json:"slow_threshold" yaml:"slow_threshold"`
	IgnoreRecordNotFoundError bool             `mapstructure:"ignore_record_not_found_error" json:"ignore_record_not_found_error" yaml:"ignore_record_not_found_error"`
	ParameterizedQueries      bool             `mapstructure:"parameterized_queries" json:"parameterized_queries" yaml:"parameterized_queries"`
	Colorful                  bool             `mapstructure:"colorful" json:"colorful" yaml:"colorful"`

	// 连接重试配置
	RetryMaxAttempts   int           `mapstructure:"retry_max_attempts" json:"retry_max_attempts" yaml:"retry_max_attempts"`
	RetryInitialDelay  time.Duration `mapstructure:"retry_initial_delay" json:"retry_initial_delay" yaml:"retry_initial_delay"`
	RetryMaxDelay      time.Duration `mapstructure:"retry_max_delay" json:"retry_max_delay" yaml:"retry_max_delay"`
	RetryBackoffFactor float64       `mapstructure:"retry_backoff_factor" json:"retry_backoff_factor" yaml:"retry_backoff_factor"`
	RetryJitterEnabled bool          `mapstructure:"retry_jitter_enabled" json:"retry_jitter_enabled" yaml:"retry_jitter_enabled"`
	RetryEnabled       bool          `mapstructure:"retry_enabled" json:"retry_enabled" yaml:"retry_enabled"`
	RetryConfigured    bool          `mapstructure:"retry_configured" json:"retry_configured" yaml:"retry_configured"`

	// 其他配置
	TablePrefix       string `mapstructure:"table_prefix" json:"table_prefix" yaml:"table_prefix"`
	SingularTable     bool   `mapstructure:"singular_table" json:"singular_table" yaml:"singular_table"`
	DisableForeignKey bool   `mapstructure:"disable_foreign_key" json:"disable_foreign_key" yaml:"disable_foreign_key"`
	PrepareStmt       bool   `mapstructure:"prepare_stmt" json:"prepare_stmt" yaml:"prepare_stmt"`
	DryRun            bool   `mapstructure:"dry_run" json:"dry_run" yaml:"dry_run"`
}

Config 数据库配置

func (*Config) SafeString

func (c *Config) SafeString() string

SafeString 返回安全的配置字符串(密码已脱敏)

func (*Config) SetCustomLogger

func (c *Config) SetCustomLogger(l SimpleLogger, level string)

SetCustomLogger 允许在 Config 层设置 GORM 日志实现,便于与外部 logger 对齐。

func (*Config) SetDefaults

func (c *Config) SetDefaults()

SetDefaults 设置默认值

func (*Config) Validate

func (c *Config) Validate() error

Validate 验证配置

type Connector added in v1.1.0

type Connector interface {
	Connect(ctx context.Context) (*gorm.DB, error)
}

Connector 负责建立数据库连接并完成基础配置(重试、命名策略、连接池)。

type ContextualLogger

type ContextualLogger interface {
	SimpleLogger
	InfoWithContext(ctx context.Context, msg string, fields ...interface{})
	WarnWithContext(ctx context.Context, msg string, fields ...interface{})
	ErrorWithContext(ctx context.Context, msg string, fields ...interface{})
}

ContextualLogger 定义支持Context的日志接口

type DB added in v1.1.0

type DB interface {
	// Exec 执行写操作,适用于 INSERT/UPDATE/DELETE 等语句。
	Exec(ctx context.Context, query string, args ...interface{}) error

	// Query 执行查询并将结果扫描到 dest。
	Query(ctx context.Context, dest interface{}, query string, args ...interface{}) error

	// Tx 启动事务并在回调中执行业务逻辑,支持传入可选的 sql.TxOptions。
	Tx(ctx context.Context, fn func(tx *gorm.DB) error, opts ...*sql.TxOptions) error

	// Raw 返回底层 *gorm.DB 以支持少数无法封装的高级用法(请谨慎使用)。
	Raw() *gorm.DB

	// SQLDB 返回底层 *sql.DB,便于执行需要专用连接的场景(如 PostgreSQL LISTEN/NOTIFY、
	// 使用特定扩展或 Driver 原生能力)。调用方负责确保合理的生命周期管理。
	SQLDB() (*sql.DB, error)
}

DB 定义对外暴露的最小能力集合,便于业务代码依赖接口而非具体实现。

绝大多数场景建议通过这些方法完成常规操作;若确需底层能力,可使用 Raw() 受控地获取底层 *gorm.DB。

type Database

type Database struct {
	// contains filtered or unexported fields
}

Database 数据库管理器,组合 Connector、Executor、HealthChecker 等职责。

func Configure added in v1.6.0

func Configure(config *Config, opts ...Option) (*Database, error)

Configure 初始化或替换默认客户端。

func GetClient added in v1.6.0

func GetClient() *Database

GetClient 获取默认客户端。

func New

func New(config *Config) (*Database, error)

New 创建新的数据库管理器

func NewWithOptions added in v1.1.0

func NewWithOptions(config *Config, opts ...Option) (*Database, error)

NewWithOptions 支持通过可选参数注入日志、钩子或自定义组件。

func (*Database) AutoMigrate

func (d *Database) AutoMigrate(dst ...interface{}) error

AutoMigrate 自动迁移数据库表

func (*Database) BeginTx added in v1.1.0

func (d *Database) BeginTx(ctx context.Context, opts ...*sql.TxOptions) (*gorm.DB, error)

BeginTx 开启事务

func (*Database) Close

func (d *Database) Close() error

Close 关闭数据库连接

func (*Database) CloseWithContext added in v1.1.0

func (d *Database) CloseWithContext(ctx context.Context) error

CloseWithContext 允许调用方传入上下文,配合生命周期钩子完成优雅关闭。

func (*Database) Exec added in v1.1.0

func (d *Database) Exec(ctx context.Context, query string, args ...interface{}) error

Exec 执行写操作

func (*Database) GetConfig

func (d *Database) GetConfig() Config

GetConfig 获取数据库配置(返回副本,防止外部修改)

func (*Database) GetDB

func (d *Database) GetDB() *gorm.DB

GetDB 获取GORM数据库实例

func (*Database) GetDriver

func (d *Database) GetDriver() string

GetDriver 获取数据库驱动类型

func (*Database) HealthCheck

func (d *Database) HealthCheck() error

HealthCheck 健康检查

func (*Database) HealthCheckWithContext

func (d *Database) HealthCheckWithContext(ctx context.Context) *HealthStatus

HealthCheckWithContext 带Context的健康检查

func (*Database) IsConnected

func (d *Database) IsConnected() bool

IsConnected 检查数据库连接状态

func (*Database) IsReadOnly

func (d *Database) IsReadOnly() bool

IsReadOnly 检查是否为只读模式(DryRun模式)

func (*Database) Ping

func (d *Database) Ping() error

Ping 测试数据库连接

func (*Database) Query added in v1.1.0

func (d *Database) Query(ctx context.Context, dest interface{}, query string, args ...interface{}) error

Query 执行查询

func (*Database) Raw added in v1.1.0

func (d *Database) Raw() *gorm.DB

Raw 提供受控的底层 *gorm.DB 访问。

func (*Database) SQLDB added in v1.1.0

func (d *Database) SQLDB() (*sql.DB, error)

SQLDB 返回底层 *sql.DB。

func (*Database) Stats

func (d *Database) Stats() PoolStats

Stats 获取连接池统计信息

func (*Database) Transaction

func (d *Database) Transaction(fn func(*gorm.DB) error) error

Transaction 事务便利方法,自动处理提交和回滚

func (*Database) TransactionWithContext

func (d *Database) TransactionWithContext(ctx context.Context, fn func(*gorm.DB) error) error

TransactionWithContext 带Context的事务便利方法

func (*Database) Tx added in v1.1.0

func (d *Database) Tx(ctx context.Context, fn func(tx *gorm.DB) error, opts ...*sql.TxOptions) error

Tx 启动事务

func (*Database) WithContext

func (d *Database) WithContext(ctx context.Context) *gorm.DB

WithContext 返回带有Context的GORM实例

type DatabaseError

type DatabaseError struct {
	Type      ErrorType
	Operation string
	Err       error
	Context   map[string]interface{}
}

DatabaseError 数据库错误结构

func NewDatabaseError

func NewDatabaseError(errorType ErrorType, operation string, err error) *DatabaseError

NewDatabaseError 创建数据库错误

func (*DatabaseError) Error

func (e *DatabaseError) Error() string

Error 实现error接口

func (*DatabaseError) Is

func (e *DatabaseError) Is(target error) bool

Is 支持errors.Is

func (*DatabaseError) Unwrap

func (e *DatabaseError) Unwrap() error

Unwrap 支持errors.Unwrap

func (*DatabaseError) WithContext

func (e *DatabaseError) WithContext(key string, value interface{}) *DatabaseError

WithContext 添加错误上下文

type ErrorType

type ErrorType int

ErrorType 错误类型

const (
	ErrorTypeConnection ErrorType = iota
	ErrorTypeValidation
	ErrorTypeQuery
	ErrorTypeTransaction
	ErrorTypeMigration
)

type Executor added in v1.1.0

type Executor interface {
	Exec(ctx context.Context, query string, args ...interface{}) error
	Query(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	Tx(ctx context.Context, fn func(tx *gorm.DB) error, opts ...*sql.TxOptions) error
	BeginTx(ctx context.Context, opts ...*sql.TxOptions) (*gorm.DB, error)
}

Executor 承载常规执行能力,便于与连接/健康检查解耦。

type GORMLogger

type GORMLogger struct {
	// contains filtered or unexported fields
}

GORMLogger 把任意 SimpleLogger 转成 gorm.logger.Interface

func (*GORMLogger) Error

func (g *GORMLogger) Error(ctx context.Context, msg string, data ...interface{})

Error 实现logger.Interface

func (*GORMLogger) Info

func (g *GORMLogger) Info(ctx context.Context, msg string, data ...interface{})

Info 实现logger.Interface

func (*GORMLogger) LogMode

func (g *GORMLogger) LogMode(l logger.LogLevel) logger.Interface

LogMode 实现接口

func (*GORMLogger) Trace

func (g *GORMLogger) Trace(ctx context.Context, begin time.Time,
	fc func() (sql string, rowsAffected int64), err error)

Trace 打印 SQL

func (*GORMLogger) Warn

func (g *GORMLogger) Warn(ctx context.Context, msg string, data ...interface{})

Warn 实现logger.Interface

type HealthChecker added in v1.1.0

type HealthChecker interface {
	Ping() error
	HealthCheck() error
	HealthCheckWithContext(ctx context.Context) *HealthStatus
}

HealthChecker 定义健康探测接口,支持 context 取消。

type HealthStatus

type HealthStatus struct {
	Healthy   bool      `json:"healthy"`
	Timestamp time.Time `json:"timestamp"`
	Driver    string    `json:"driver"`
	Errors    []string  `json:"errors,omitempty"`
	Warnings  []string  `json:"warnings,omitempty"`
	Stats     PoolStats `json:"stats"`
}

HealthStatus 健康检查状态

type Hooks added in v1.1.0

type Hooks struct {
	BeforeConnect func(cfg *Config)
	AfterConnect  func(db *gorm.DB)

	BeforeClose func(ctx context.Context, db *gorm.DB) error
	AfterClose  func(ctx context.Context, closeErr error)

	BeforeProbe func(ctx context.Context) error
	AfterProbe  func(ctx context.Context, probeErr error)
}

Hooks 定义生命周期扩展点,便于调用方在关键节点插入自定义逻辑。

type Option added in v1.1.0

type Option func(*Database)

Option 允许在构建 Database 时注入可选配置,例如 Logger、Hooks 等。

func WithConnector added in v1.1.0

func WithConnector(connector Connector) Option

Option helpers for custom components

func WithExecutor added in v1.1.0

func WithExecutor(executor Executor) Option

func WithHealthChecker added in v1.1.0

func WithHealthChecker(healthChecker HealthChecker) Option

func WithHooks added in v1.1.0

func WithHooks(h Hooks) Option

WithHooks 设置生命周期钩子。

func WithLogger added in v1.1.0

func WithLogger(l SimpleLogger) Option

WithLogger 设置用于启动、重试和健康检查日志的 SimpleLogger。

type PoolConfigurator added in v1.1.0

type PoolConfigurator interface {
	Configure(db *gorm.DB) error
}

PoolConfigurator 允许对底层 *sql.DB 进行池参数配置。

type PoolStats

type PoolStats struct {
	OpenConnections   int
	IdleConnections   int
	WaitCount         int64
	WaitDuration      time.Duration
	MaxIdleClosed     int64
	MaxLifetimeClosed int64
}

PoolStats 连接池统计信息

type SimpleLogger

type SimpleLogger interface {
	Info(msg string, fields ...interface{})
	Warn(msg string, fields ...interface{})
	Error(msg string, fields ...interface{})
}

SimpleLogger 定义基础日志接口

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL