3月6日 21:37
How to connect to different databases with GORM?
GORM supports multiple databases, including MySQL, PostgreSQL, SQLite, SQL Server, etc. Here are the methods and considerations for connecting to different databases.
Connecting to MySQL
Basic Connection
goimport ( "gorm.io/driver/mysql" "gorm.io/gorm" ) dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
Connection Parameters
user: Database usernamepassword: Database passwordtcp(127.0.0.1:3306): Host and portdbname: Database namecharset=utf8mb4: Character setparseTime=True: Parse timeloc=Local: Timezone setting
Advanced Configuration
godsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local&timeout=10s&readTimeout=30s&writeTimeout=30s" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), NowFunc: func() time.Time { return time.Now().Local() }, })
Connecting to PostgreSQL
Basic Connection
goimport ( "gorm.io/driver/postgres" "gorm.io/gorm" ) dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
Connection Parameters
host: Database hostuser: Database usernamepassword: Database passworddbname: Database nameport: Port numbersslmode: SSL modeTimeZone: Timezone setting
Using URL Format
godsn := "postgres://gorm:gorm@localhost:9920/gorm?sslmode=disable&timezone=Asia/Shanghai" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
Connecting to SQLite
Basic Connection
goimport ( "gorm.io/driver/sqlite" "gorm.io/gorm" ) db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
In-Memory Database
godb, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
Connecting to SQL Server
Basic Connection
goimport ( "gorm.io/driver/sqlserver" "gorm.io/gorm" ) dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})
Connection Pool Configuration
Get Underlying SQL DB
gosqlDB, err := db.DB() if err != nil { panic("failed to get database connection") }
Configure Connection Pool Parameters
go// Set maximum number of idle connections in the connection pool sqlDB.SetMaxIdleConns(10) // Set maximum number of open database connections sqlDB.SetMaxOpenConns(100) // Set maximum time a connection can be reused sqlDB.SetConnMaxLifetime(time.Hour) // Set maximum idle time for connection sqlDB.SetConnMaxIdleTime(10 * time.Minute)
GORM Configuration Options
Basic Configuration
godb, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ // Skip default transaction SkipDefaultTransaction: true, // Disable foreign key constraints DisableForeignKeyConstraintWhenMigrating: true, // Ignore data errors IgnoreRelationshipsWhenMigrating: true, })
Logger Configuration
goimport "gorm.io/gorm/logger" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), }) // Custom Logger newLogger := logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{ SlowThreshold: time.Second, // Slow query threshold LogLevel: logger.Info, // Log level IgnoreRecordNotFoundError: true, // Ignore record not found error Colorful: true, // Colorful output }, ) db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: newLogger, })
Naming Strategy Configuration
goimport "gorm.io/gorm/schema" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ NamingStrategy: schema.NamingStrategy{ SingularTable: true, // Use singular table names NoLowerCase: true, // Don't convert to lowercase }, })
Database-Specific Configuration
MySQL Specific Configuration
goimport "gorm.io/driver/mysql" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn, DefaultStringSize: 256, // Default string length DisableDatetimePrecision: true, // Disable datetime precision DontSupportRenameIndex: true, // Don't support rename index DontSupportRenameColumn: true, // Don't support rename column SkipInitializeWithVersion: false, // Auto configure based on version }), &gorm.Config{})
PostgreSQL Specific Configuration
goimport "gorm.io/driver/postgres" db, err := gorm.Open(postgres.New(postgres.Config{ DSN: dsn, PreferSimpleProtocol: false, // Disable prepared statement }), &gorm.Config{})
Connection Management Best Practices
1. Use Connection Pool
gosqlDB, _ := db.DB() sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour)
2. Test Connection
gosqlDB, _ := db.DB() if err := sqlDB.Ping(); err != nil { panic("failed to connect to database") }
3. Graceful Shutdown
gosqlDB, _ := db.DB() defer sqlDB.Close()
4. Connection Retry
gofunc connectWithRetry(dsn string, maxRetries int) (*gorm.DB, error) { var db *gorm.DB var err error for i := 0; i < maxRetries; i++ { db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err == nil { return db, nil } time.Sleep(time.Second * time.Duration(i+1)) } return nil, err }
Environment Variable Configuration
Using Environment Variables
goimport "os" dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
Multiple Database Connections
Connecting to Multiple Databases
go// Primary database primaryDB, err := gorm.Open(mysql.Open(primaryDSN), &gorm.Config{}) // Replica database replicaDB, err := gorm.Open(mysql.Open(replicaDSN), &gorm.Config{}) // Use different databases primaryDB.Create(&user) replicaDB.First(&user, 1)
Notes
- Connection Pool Size: Set connection pool size reasonably based on application concurrency
- Timeout Settings: Set reasonable connection timeout and read/write timeout
- Error Handling: Properly handle connection errors and query errors
- Resource Release: Ensure database connection is closed when application exits
- Security: Don't hardcode database password in code
- Monitoring: Monitor connection pool usage, discover problems in time
Common Questions
Q: How to handle connection timeout?
A: Set timeout parameter in DSN, or use context to set timeout.
Q: How large should the connection pool be?
A: Adjust based on application concurrency and database server performance, usually MaxOpenConns set to 2-4 times CPU cores.
Q: How to switch databases?
A: Just need to change the corresponding driver and DSN, other code basically doesn't need modification.
Q: How to handle database connection leaks?
A: Use defer to ensure connection is closed, monitor connection pool status, set reasonable connection lifecycle.