
TORM提供了灵活的配置选项,支持多种数据库和连接参数的配置。本文档详细介绍了所有可用的配置选项。
📋 基本配置
数据库连接配置
config := &db.Config{
Driver: "mysql",
Host: "localhost",
Port: 3306,
Database: "myapp",
Username: "root",
Password: "password",
Charset: "utf8mb4",
MaxOpenConns: 100,
MaxIdleConns: 10,
ConnMaxLifetime: time.Hour,
ConnMaxIdleTime: time.Minute * 30,
LogQueries: true,
Options: map[string]string{
"parseTime": "true",
"loc": "Local",
},
}
🗄️ 数据库特定配置
MySQL 配置
mysqlConfig := &db.Config{
Driver: "mysql",
Host: "localhost",
Port: 3306,
Database: "myapp",
Username: "root",
Password: "password",
Charset: "utf8mb4",
Options: map[string]string{
"parseTime": "true",
"loc": "Local",
"charset": "utf8mb4",
"collation": "utf8mb4_unicode_ci",
"timeout": "30s",
"readTimeout": "30s",
"writeTimeout": "30s",
"allowNativePasswords": "true",
"tls": "false",
},
}
PostgreSQL 配置
postgresConfig := &db.Config{
Driver: "postgres",
Host: "localhost",
Port: 5432,
Database: "myapp",
Username: "postgres",
Password: "password",
SSLMode: "disable",
Options: map[string]string{
"sslmode": "disable",
"connect_timeout": "30",
"statement_timeout": "30000",
"lock_timeout": "30000",
"idle_in_transaction_session_timeout": "30000",
"search_path": "public",
"application_name": "github.com/zhoudm1743/torm",
},
}
SQLite 配置
sqliteConfig := &db.Config{
Driver: "sqlite",
Database: "./data/app.db",
Options: map[string]string{
"cache": "shared",
"mode": "rwc",
"journal_mode": "WAL",
"synchronous": "NORMAL",
"cache_size": "1000",
"temp_store": "memory",
"foreign_keys": "on",
},
}
MongoDB 配置
mongoConfig := &db.Config{
Driver: "mongodb",
Host: "localhost",
Port: 27017,
Database: "myapp",
Username: "",
Password: "",
Options: map[string]string{
"authSource": "admin",
"replicaSet": "",
"ssl": "false",
"connectTimeoutMS": "30000",
"socketTimeoutMS": "30000",
"serverSelectionTimeoutMS": "30000",
"maxPoolSize": "100",
"minPoolSize": "5",
"maxIdleTimeMS": "300000",
"retryWrites": "true",
"w": "majority",
"readPreference": "primary",
},
}
SQL Server 配置
sqlserverConfig := &db.Config{
Driver: "sqlserver",
Host: "localhost",
Port: 1433,
Database: "myapp",
Username: "sa",
Password: "password",
Options: map[string]string{
"connection timeout": "30",
"dial timeout": "15",
"keepAlive": "30",
"encrypt": "disable",
"TrustServerCertificate": "true",
"app name": "github.com/zhoudm1743/torm",
"log": "1",
},
}
🔧 连接池配置
详细连接池参数
config := &db.Config{
MaxOpenConns: 100,
MaxIdleConns: 10,
ConnMaxLifetime: time.Hour,
ConnMaxIdleTime: time.Minute * 30,
}
不同场景的连接池建议
高并发Web应用
config := &db.Config{
MaxOpenConns: 200,
MaxIdleConns: 50,
ConnMaxLifetime: time.Hour * 2,
ConnMaxIdleTime: time.Minute * 15,
}
批处理应用
config := &db.Config{
MaxOpenConns: 50,
MaxIdleConns: 10,
ConnMaxLifetime: time.Hour * 4,
ConnMaxIdleTime: time.Hour,
}
微服务应用
config := &db.Config{
MaxOpenConns: 20,
MaxIdleConns: 5,
ConnMaxLifetime: time.Minute * 30,
ConnMaxIdleTime: time.Minute * 10,
}
📝 日志配置
基本日志配置
config := &db.Config{
LogQueries: true,
}
logger := logrus.New()
migrator := migration.NewMigrator(conn, logger)
自定义日志器
type CustomLogger struct {
logger *logrus.Logger
}
func (l *CustomLogger) Debug(msg string, args ...interface{}) {
l.logger.WithFields(toFields(args)).Debug(msg)
}
func (l *CustomLogger) Info(msg string, args ...interface{}) {
l.logger.WithFields(toFields(args)).Info(msg)
}
func (l *CustomLogger) Error(msg string, args ...interface{}) {
l.logger.WithFields(toFields(args)).Error(msg)
}
func toFields(args []interface{}) logrus.Fields {
fields := logrus.Fields{}
for i := 0; i < len(args)-1; i += 2 {
if key, ok := args[i].(string); ok {
fields[key] = args[i+1]
}
}
return fields
}
🌍 环境变量配置
支持的环境变量
export TORM_DB_DRIVER=mysql
export TORM_DB_HOST=localhost
export TORM_DB_PORT=3306
export TORM_DB_NAME=myapp
export TORM_DB_USER=root
export TORM_DB_PASSWORD=password
export TORM_DB_CHARSET=utf8mb4
export TORM_MAX_OPEN_CONNS=100
export TORM_MAX_IDLE_CONNS=10
export TORM_CONN_MAX_LIFETIME=3600
export TORM_CONN_MAX_IDLE_TIME=1800
export TORM_LOG_QUERIES=true
export TORM_LOG_LEVEL=info
export TORM_SSL_MODE=disable
export TORM_SSL_CERT=/path/to/cert.pem
export TORM_SSL_KEY=/path/to/key.pem
export TORM_SSL_CA=/path/to/ca.pem
从环境变量加载配置
func LoadConfigFromEnv() *db.Config {
config := &db.Config{
Driver: getEnv("TORM_DB_DRIVER", "mysql"),
Host: getEnv("TORM_DB_HOST", "localhost"),
Port: getEnvInt("TORM_DB_PORT", 3306),
Database: getEnv("TORM_DB_NAME", ""),
Username: getEnv("TORM_DB_USER", ""),
Password: getEnv("TORM_DB_PASSWORD", ""),
Charset: getEnv("TORM_DB_CHARSET", "utf8mb4"),
MaxOpenConns: getEnvInt("TORM_MAX_OPEN_CONNS", 100),
MaxIdleConns: getEnvInt("TORM_MAX_IDLE_CONNS", 10),
ConnMaxLifetime: time.Duration(getEnvInt("TORM_CONN_MAX_LIFETIME", 3600)) * time.Second,
ConnMaxIdleTime: time.Duration(getEnvInt("TORM_CONN_MAX_IDLE_TIME", 1800)) * time.Second,
LogQueries: getEnvBool("TORM_LOG_QUERIES", false),
SSLMode: getEnv("TORM_SSL_MODE", "disable"),
}
return config
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}
func getEnvBool(key string, defaultValue bool) bool {
if value := os.Getenv(key); value != "" {
if boolValue, err := strconv.ParseBool(value); err == nil {
return boolValue
}
}
return defaultValue
}
📁 配置文件支持
YAML 配置文件
database:
connections:
default:
driver: mysql
host: localhost
port: 3306
database: myapp
username: root
password: password
charset: utf8mb4
pool:
max_open_conns: 100
max_idle_conns: 10
conn_max_lifetime: 3600
conn_max_idle_time: 1800
options:
parseTime: "true"
loc: "Local"
read_replica:
driver: mysql
host: read-replica.example.com
port: 3306
database: myapp
username: readonly
password: password
charset: utf8mb4
pool:
max_open_conns: 50
max_idle_conns: 5
logging:
queries: true
level: info
cache:
enabled: true
default_ttl: 300
cleanup_interval: 600
JSON 配置文件
{
"database": {
"connections": {
"default": {
"driver": "mysql",
"host": "localhost",
"port": 3306,
"database": "myapp",
"username": "root",
"password": "password",
"charset": "utf8mb4",
"pool": {
"max_open_conns": 100,
"max_idle_conns": 10,
"conn_max_lifetime": 3600,
"conn_max_idle_time": 1800
},
"options": {
"parseTime": "true",
"loc": "Local"
}
}
},
"logging": {
"queries": true,
"level": "info"
}
}
}
配置文件加载器
func LoadConfigFromYAML(filename string) (*db.Config, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
var configData struct {
Database struct {
Connections map[string]struct {
Driver string `yaml:"driver"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Database string `yaml:"database"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Charset string `yaml:"charset"`
Pool struct {
MaxOpenConns int `yaml:"max_open_conns"`
MaxIdleConns int `yaml:"max_idle_conns"`
ConnMaxLifetime int `yaml:"conn_max_lifetime"`
ConnMaxIdleTime int `yaml:"conn_max_idle_time"`
} `yaml:"pool"`
Options map[string]string `yaml:"options"`
} `yaml:"connections"`
} `yaml:"database"`
}
err = yaml.Unmarshal(data, &configData)
if err != nil {
return nil, err
}
defaultConn := configData.Database.Connections["default"]
config := &db.Config{
Driver: defaultConn.Driver,
Host: defaultConn.Host,
Port: defaultConn.Port,
Database: defaultConn.Database,
Username: defaultConn.Username,
Password: defaultConn.Password,
Charset: defaultConn.Charset,
MaxOpenConns: defaultConn.Pool.MaxOpenConns,
MaxIdleConns: defaultConn.Pool.MaxIdleConns,
ConnMaxLifetime: time.Duration(defaultConn.Pool.ConnMaxLifetime) * time.Second,
ConnMaxIdleTime: time.Duration(defaultConn.Pool.ConnMaxIdleTime) * time.Second,
Options: defaultConn.Options,
}
return config, nil
}
🔒 安全配置
SSL/TLS 配置
mysqlSSLConfig := &db.Config{
Driver: "mysql",
Host: "secure-mysql.example.com",
Port: 3306,
Database: "myapp",
Username: "secure_user",
Password: "secure_password",
Options: map[string]string{
"tls": "custom",
"tls-ca": "/path/to/ca.pem",
"tls-cert": "/path/to/cert.pem",
"tls-key": "/path/to/key.pem",
"tls-verify": "true",
},
}
postgresSSLConfig := &db.Config{
Driver: "postgres",
Host: "secure-postgres.example.com",
Port: 5432,
Database: "myapp",
Username: "secure_user",
Password: "secure_password",
SSLMode: "require",
Options: map[string]string{
"sslcert": "/path/to/cert.pem",
"sslkey": "/path/to/key.pem",
"sslrootcert": "/path/to/ca.pem",
},
}
密码安全
config := &db.Config{
Driver: "mysql",
Host: os.Getenv("DB_HOST"),
Port: 3306,
Database: os.Getenv("DB_NAME"),
Username: os.Getenv("DB_USER"),
Password: os.Getenv("DB_PASSWORD"),
}
func LoadSecureConfig() *db.Config {
password := getSecretFromVault("database/password")
return &db.Config{
Password: password,
}
}
🎯 最佳实践
1. 分环境配置
func GetConfigForEnvironment(env string) *db.Config {
switch env {
case "development":
return &db.Config{
Driver: "sqlite",
Database: "dev.db",
LogQueries: true,
MaxOpenConns: 10,
}
case "testing":
return &db.Config{
Driver: "sqlite",
Database: ":memory:",
LogQueries: false,
MaxOpenConns: 5,
}
case "production":
return &db.Config{
Driver: "mysql",
Host: os.Getenv("DB_HOST"),
Port: 3306,
Database: os.Getenv("DB_NAME"),
Username: os.Getenv("DB_USER"),
Password: os.Getenv("DB_PASSWORD"),
MaxOpenConns: 200,
MaxIdleConns: 50,
ConnMaxLifetime: time.Hour * 2,
LogQueries: false,
}
default:
panic("unknown environment: " + env)
}
}
2. 配置验证
func ValidateConfig(config *db.Config) error {
if config.Driver == "" {
return fmt.Errorf("driver is required")
}
if config.Driver != "sqlite" && config.Host == "" {
return fmt.Errorf("host is required for driver %s", config.Driver)
}
if config.Database == "" {
return fmt.Errorf("database is required")
}
if config.MaxOpenConns <= 0 {
return fmt.Errorf("max_open_conns must be positive")
}
if config.MaxIdleConns > config.MaxOpenConns {
return fmt.Errorf("max_idle_conns cannot be greater than max_open_conns")
}
return nil
}
3. 配置热加载
type ConfigManager struct {
config *db.Config
configFile string
mutex sync.RWMutex
}
func NewConfigManager(configFile string) *ConfigManager {
return &ConfigManager{
configFile: configFile,
}
}
func (cm *ConfigManager) LoadConfig() error {
config, err := LoadConfigFromYAML(cm.configFile)
if err != nil {
return err
}
cm.mutex.Lock()
cm.config = config
cm.mutex.Unlock()
return nil
}
func (cm *ConfigManager) GetConfig() *db.Config {
cm.mutex.RLock()
defer cm.mutex.RUnlock()
return cm.config
}
func (cm *ConfigManager) WatchConfig() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
err = watcher.Add(cm.configFile)
if err != nil {
log.Fatal(err)
}
for {
select {
case event := <-watcher.Events:
if event.Op&fsnotify.Write == fsnotify.Write {
log.Println("配置文件已修改,重新加载...")
if err := cm.LoadConfig(); err != nil {
log.Printf("重新加载配置失败: %v", err)
} else {
log.Println("配置重新加载成功")
}
}
case err := <-watcher.Errors:
log.Printf("配置文件监控错误: %v", err)
}
}
}