Revel框架连接MySQL必须手动集成GORM v2+,需用mysql.Open(dsn)封装DSN并传入gorm.Open,显式导入驱动、配置parseTime=true&loc=Local、初始化后调db.DB().SetMaxOpenConns(),且DB实例须通过InterceptFunc按请求注入而非全局裸用。

Revel 框架本身不带 ORM,连接 MySQL 必须手动集成 GORM(v2+),且不能只传 DSN 字符串——直接 gorm.Open("user:pass@tcp(...)") 会 panic 或报 "invalid connection"。
gorm.Open() 第一个参数必须是 driver 实例,不是字符串
GORM v2+ 废弃了纯字符串 DSN 入口,要求显式传入驱动构造函数。常见错误是复制旧教程代码,漏掉 mysql.Open() 这一层封装。
- 正确写法:
gorm.Open(mysql.Open(dsn), &gorm.Config{}),其中mysql来自gorm.io/driver/mysql - 必须显式
import "gorm.io/driver/mysql",否则编译失败或运行时报 "driver not found" - DSN 中建议固定加上
parseTime=True&loc=Local,否则time.Time字段读出来是零值或解析失败 - 不要在 controller 里每次请求都调
gorm.Open()——它创建的是带连接池的长期实例,应只初始化一次
连接池参数得在 gorm.Open 之后单独设置
gorm.Config{} 只控制 ORM 层行为(如日志、命名策略),不触达底层 *sql.DB。连接池参数无效,往往是因为只改了 Config 却没调 db.DB().SetMaxOpenConns()。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 初始化后立刻执行:
db.DB().SetMaxOpenConns(50)、db.DB().SetMaxIdleConns(10) - MySQL 默认
max_connections通常为 151,线上部署时需确保SetMaxOpenConns不超过该值,否则数据库拒绝新连接 - 若用连接池健康检查,建议加一次探活:
db.Exec("SELECT 1"),避免首请求因 DNS 解析失败而卡住
DB 实例不能全局裸用,必须按请求注入
把 var DB *gorm.DB 直接 import 到 model 或 controller 里调用,看似能跑,但并发下极易出现事务错乱、Preload 数据混杂、甚至 panic: invalid memory address。
- 正确做法:在
app/init.go的init()或AppInit()中初始化DB,再用revel.InterceptFunc在BEFORE阶段注入:c.Params.Set("db", DB) - controller 中取用:
db := c.Params.Get("db").(*gorm.DB),类型断言不可省略 - 若需主从分离或多租户,filter 内应根据
c.Request.Host或路由动态选库,而不是硬编码用同一个DB - 事务也得走同一路径:
tx := db.Begin()→c.Params.Set("tx", tx)→ controller 中取tx并确保defer tx.Commit()或Rollback()
最易被忽略的是 DSN 中的 loc=Local 和连接池的 SetMaxOpenConns 调用时机——前者影响时间字段解析,后者不调就等于没配,高并发时连接数会悄无声息地打满数据库。










