GORM V2连接MySQL必须用gorm.io/driver/mysql驱动并下划线导入,DSN需含parseTime=True&loc=Local,gorm.Open前须配置*sql.DB连接池参数,AutoMigrate仅新增表/字段/索引,不删改字段。

直接上手 GORM 不需要先学 database/sql,但必须立刻区分清楚:gorm.io/driver/mysql 和 github.com/go-sql-driver/mysql 是两套完全不兼容的驱动,混用会导致 invalid driver name 或连接静默失败。
gorm.Open 为什么总 panic?检查 DSN 和驱动导入顺序
最常见的崩溃不是代码写错,而是 DSN 格式不对或驱动没真正加载。GORM V2 要求 DSN 必须带 parseTime=True 和 loc=Local,缺一不可 —— 否则 time.Time 字段会解析成零值,且错误不报在 err 里,而是在后续查询时才暴露。
- 正确 DSN 示例:
"root:pass@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local" - 必须用
import _ "gorm.io/driver/mysql"(下划线导入),否则mysql.Open会是 nil -
gorm.Open内部会自动Ping(),所以如果数据库不可达,err一定非空,别跳过判断
AutoMigrate 不会改字段类型,也删不了列
db.AutoMigrate(&User{}) 看起来像“一键同步”,实际只做加法:新增表、新增字段、新增索引。它不会修改已有字段长度、类型或约束,更不会删除任何列 —— 这是故意设计,防止误操作炸掉生产数据。
- 比如把
Name string `gorm:"size:32"`改成size:64,再次AutoMigrate不生效 - 想改类型?得手动执行
ALTER TABLE,或换用migrate工具(如 gormigrate) - 开发阶段可接受,但上线前务必确认表结构和模型严格一致,否则
Scan或Create可能静默截断
gorm.Model 自带字段不是银弹,注意时间字段行为
用 type User struct { gorm.Model } 确实省事,但它强制引入 CreatedAt、UpdatedAt、DeletedAt,且默认全部为 time.Time 类型。问题在于:
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
立即学习“go语言免费学习笔记(深入)”;
-
CreatedAt和UpdatedAt在插入/更新时自动赋值,但如果你自己设置了值(比如从 JSON 解析),GORM 会覆盖它 —— 除非显式关掉:db.Session(&gorm.Session{AllowGlobalUpdate: true}).Create(&u) -
DeletedAt开启软删除后,Delete()不走DELETE FROM,而是UPDATE SET deleted_at = NOW(),但First()默认就忽略软删除记录,要查已删数据得加Unscoped() - 如果数据库字段是
TIMESTAMP(如 MySQL),而 Go 模型用time.Time,时区不一致会导致时间偏移,必须确保 DSN 中loc=Local且数据库时区配置匹配
连接池参数不配等于裸奔,尤其在并发场景
*gorm.DB 底层包装的是 *sql.DB,但 GORM 不帮你设连接池参数。没配 SetMaxOpenConns 和 SetMaxIdleConns,高并发下要么连不上(too many connections),要么连接频繁创建销毁拖垮性能。
- 典型配置:
sqlDB.SetMaxOpenConns(50)、sqlDB.SetMaxIdleConns(10)、sqlDB.SetConnMaxLifetime(1h) -
SetMaxOpenConns建议设为 QPS × 平均 SQL 耗时(秒),例如 100 QPS × 0.2s = 20,再留点余量 - 别漏掉
SetConnMaxIdleTime(Go 1.15+),避免空闲连接被中间件或数据库主动踢掉后还留在池里,下次用时报connection refused
最易被忽略的其实是日志开关 —— gorm.Config{Logger: logger.Default.LogMode(logger.Info)} 在开发期必须开,否则 SQL 错误、慢查询、空结果都看不到;但上线后若忘记切到 logger.Silent,日志文件会撑爆磁盘。

















