【Gorm】连接到数据库
-
DSN(Data Source Name)是一个字符串,用来告诉数据库驱动如何连接到数据库。理解 DSN 的构成有助于正确配置和调试数据库连接。
- 用户名和密码
- 示例(MySQL):
user:pass
user
:连接数据库的用户名。pass
:对应用户的密码。
- 示例(MySQL):
- 地址和端口
- 示例(MySQL):
@tcp(127.0.0.1:3306)
127.0.0.1
:数据库服务器地址,通常为 IP 地址或域名。3306
:数据库服务端口,MySQL 默认端口是 3306。
- 示例(MySQL):
- 数据库名称
- 示例(MySQL):
/dbname
dbname
:要连接的具体数据库名称。
- 示例(MySQL):
- 附加参数
- 参数以问号
?
开始,通过&
分隔多个键值对。 - 常见参数包括:
- charset:指定字符集,如
charset=utf8mb4
,保证支持完整的 UTF-8 编码。 - parseTime:如
parseTime=True
,表示自动解析数据库中的时间字段为 Go 的time.Time
类型。 - loc:如
loc=Local
,设置时区为本地时区,确保时间数据正确处理。
- charset:指定字符集,如
- 参数以问号
- 用户名和密码
-
数据库驱动:
- 简单来说,数据库驱动就像不同国家的翻译官,帮助你的程序把通用的数据库操作指令“翻译”为具体数据库能理解的话,从而实现数据的存取和操作。
-
支持的数据库类型
- GORM 官方支持 MySQL、PostgreSQL、SQLite、SQL Server、TiDB 等多种数据库,还有第三方支持 Clickhouse 等数据库。
-
连接数据库的基本方式
-
导入对应驱动包:根据目标数据库选择对应的驱动包,例如 MySQL 使用
"gorm.io/driver/mysql"
、PostgreSQL 使用"gorm.io/driver/postgres"
、SQLite 使用"gorm.io/driver/sqlite"
等。 -
构造 DSN(Data Source Name)字符串:DSN 字符串包含用户名、密码、数据库地址、端口、数据库名、字符集、时区以及其他参数。
-
例如,对于 MySQL:
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情 dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
-
对于 PostgreSQL:
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{})
-
-
使用现有数据库连接:可以先使用标准库
database/sql
获取一个sql.DB
对象,再将其传入 GORM 进行初始化。sqlDB, err := sql.Open("pgx", "mydb_dsn") gormDB, err := gorm.Open(postgres.New(postgres.Config{ Conn: sqlDB, }), &gorm.Config{})
-
-
高级配置选项
-
不同驱动支持一些额外的高级配置参数,例如:
-
MySQL:可以设置默认字符串长度、禁用 datetime 精度(适用于旧版本 MySQL)、处理索引重命名等。
db, err := gorm.Open(mysql.New(mysql.Config{ DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name DefaultStringSize: 256, // string 类型字段的默认长度 DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持 DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引 DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列 SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置 }), &gorm.Config{})
-
PostgreSQL:支持使用 pgx 驱动,并可设置是否启用 prepared statement 缓存。
db, err := gorm.Open(postgres.New(postgres.Config{ DSN: "user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai", PreferSimpleProtocol: true, // disables implicit prepared statement usage }), &gorm.Config{})
-
TiDB:支持特定的标签如
default:auto_random()
来调用 TiDB 的自动随机主键功能,以及注意特定版本支持 SAVEPOINT、FOREIGN KEY 等功能。
-
-
连接池管理:GORM 内部基于
database/sql
维护连接池,允许设置最大空闲连接数、最大打开连接数和连接的最大重用时间:sqlDB, _ := db.DB() sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour)
-
-
自定义驱动
- GORM 允许通过
DriverName
选项来自定义驱动名称,从而使用其他第三方驱动。
import ( _ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres" "gorm.io/gorm" ) db, err := gorm.Open(postgres.New(postgres.Config{ DriverName: "cloudsqlpostgres", DSN: "host=project:region:instance user=postgres dbname=postgres password=password sslmode=disable", })
- GORM 允许通过