发布于2026-07-19 阅读(0)
扫一扫,手机访问
GORM v2 上手之初,最常把人卡住的,无非就三件事:连不上、查不到、建不成表。只要把初始化和模型定义那几条硬规矩摸清楚,后面的增删改查基本就是顺水推舟的事。

不是DSN写错了,而是用了GORM v1的写法却装了v2——gorm.Open("mysql", dsn) 在v2中已彻底移除,直接报 unsupported driver。那正确的做法是什么?
sql.Open 拿到 *sql.DB,再传给 gorm.Openmysql.New(mysql.Config{Conn: sqlDB}),不能直接传 mysql.Open(dsn)sqlDB.SetMaxOpenConns() 和 SetMaxIdleConns() 必须在 gorm.Open 前调,否则无效& 是普通字符(Go 字符串里写 & 即可),不是 HTML 实体 &结构体字段根本没被 GORM 识别出来,它退回到了默认字段集。主键和字段命名是硬门槛,绕不过去。
ID(首字母大写),或显式加标签:ID uint `gorm:"primaryKey"`;id、Id、UserId 都不认UserName → user_name;想保留原名得加 gorm:"column:UserName"users → user),初始化时加配置:&gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}}AutoMigrate 不删字段、不改类型,只新增字段和索引;想重试请先 db.Migrator().DropTable(&User{})Where(&User{Name: "Alice", Age: 0}) 这种写法会把所有字段(包括零值)塞进 WHERE 条件,最终生成 WHERE name = 'Alice' AND age = 0,而你本意可能是“只按非空字段过滤”。那怎么避免?
0、""、false、time.Time{})**不忽略**,而是照常参与条件拼接Where("name = ?", name).Where("age > ?", 0)map[string]interface{},只放非零/非空的 key-valueuser_name,struct tag 就得写 gorm:"column:user_name"这是 GORM v2 官方推荐的批量插入方式,但默认行为容易引发数据不一致。需要留心几个点:
db.Create(&users) 传切片——v2 默认仍是一条一条插,性能差且易耗尽连接池CreateInBatches 默认不开启事务,某一批失败,前面批次已提交;如需强一致性,必须显式包裹 db.Transaction()RETURNING,所以即使加了 Clauses(clause.Returning{}),ID 也不会回填到 struct 切片中max_allowed_packet 限制还有一个容易被忽略的细节:GORM v2 的钩子(如 BeforeCreate)默认不被 Sa ve() 触发,必须用 Create() 或 Update();还有读写分离场景下,事务内所有操作强制走主库——哪怕你只写了 Find(),也得注意时序一致性。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8