GORM v2 连接 MySQL 失败主因是 DSN 格式错误、驱动未导入或连接池未配置;必须 import _ "gorm.io/driver/mysql",DSN 含 user:pass@tcp(ip:port)/db?charset=utf8mb4&parseTime=True&loc=Local,并在 gorm.Open 后调用 db.DB().SetMaxOpenConns() 等设置连接池。

GORM v2 连接 MySQL 失败,90% 是 DSN 格式错、驱动没导入,或连接池没设——不是代码写得不够“优雅”,而是骨架没搭对。
mysql.Open() 的 DSN 字符串必须带 tcp 和完整参数
DSN 不是填个 host:port 就完事。GORM v2 强制要求用 mysql.Open() 包裹完整字符串,且 tcp(127.0.0.1:3306) 中的 tcp 不能省,括号不能漏,IP 和端口必须可连通。
-
user:pass@tcp(127.0.0.1:3306)/dbname是最低可用骨架;缺任何一部分(比如写成@/dbname或@tcp(:3306))都会触发dial tcp: unknown port tcp/ -
charset=utf8mb4必须显式加,否则中文插入失败或乱码 -
parseTime=True决定time.Time字段能否正常读写;不加会导致所有时间字段为零值 -
loc=Local避免容器环境(默认 UTC)和应用本地时区(如 CST)错位,尤其影响CreatedAt等字段
import _ "gorm.io/driver/mysql" 缺一不可
很多报错看似是连接失败,实际是 Go 编译器根本没加载 MySQL 驱动——因为忘了那行带下划线的导入。
- 必须写
import _ "gorm.io/driver/mysql",不是import "gorm.io/driver/mysql" - 如果用旧版 GORM(
jinzhu/gorm),对应驱动是import _ "github.com/go-sql-driver/mysql",但 v2 不兼容 - 没有这行,
mysql.Open会 panic:undefined: mysql或运行时报driver: unknown driver "mysql" (forgotten import?)
连接池配置必须在 gorm.Open 之后单独调用
GORM 自身不接管连接池参数,gorm.Config{} 里设不了 MaxOpenConns。漏掉这步,压测时大概率出现 dial tcp 127.0.0.1:3306: connect: cannot assign requested address。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 先用
db.DB()拿到底层*sql.DB实例 - 再调用
SetMaxOpenConns(100)、SetMaxIdleConns(20)、SetConnMaxLifetime(time.Hour) -
SetMaxIdleConns值不能大于SetMaxOpenConns,否则空闲连接堆积,占满数据库许可 -
SetConnMaxLifetime推荐 ≤ 1 小时,防止 MySQL 的wait_timeout主动断连引发invalid connection
AutoMigrate 失败别急着查 DSN,先看结构体定义
报 Error 1046: No database selected 或字段没建上,大概率不是连接问题,而是模型没对齐。
- 结构体字段必须首字母大写(导出),否则 GORM 无法反射读取
- 主键要显式声明:
ID uint `gorm:"primaryKey"`,不能只靠gorm.Model(它只是个含字段的 struct,不是自动注册机制) - 默认表名是复数小写(
users),若想映射到user表,要么加 tag:type User struct { ... } `gorm:"tableName:user"`,要么全局设置gorm.NamingStrategy{SingularTable: true}
最常被跳过的点:配置加载为空导致 DSN 变成 :@tcp(:)/——这种错误不会在编译时报,而是在运行时炸开,且日志里只显示底层 net.Dial 错误,容易误判为网络问题。务必在拼 DSN 前校验每个变量非空。










