
使用 gorm 的 `create` 或 `save` 方法插入新记录后,gorm 会自动将数据库生成的主键(如 mysql 的 `auto_increment` 值)回填到结构体字段中,无需额外查询即可直接访问。
在基于 GORM(v1.x,如 github.com/jinzhu/gorm)开发的应用中,当你调用 db.Create() 或 db.Save() 插入一条新记录时,GORM 会自动利用底层数据库驱动(如 mysql)提供的机制(例如 MySQL 的 LAST_INSERT_ID())获取刚插入行的自增主键,并原地更新传入结构体的主键字段。这意味着你无需执行额外的 SELECT LAST_INSERT_ID() 查询,也无需手动调用 db.LastInsertId()(该方法在 GORM v1 中并不存在,属常见误解)。
✅ 正确做法如下:
type User struct {
ID uint `gorm:"primaryKey;autoIncrement"` // 推荐使用 ID(GORM 默认主键字段名)
Name string
}
user := User{Name: "jinzhu"}
result := db.Create(&user)
if result.Error != nil {
log.Fatal(result.Error)
}
// 此时 user.ID 已被自动赋值为数据库返回的自增ID
fmt.Printf("New user ID: %d\n", user.ID)
// 若需获取完整实体,user 变量本身即为最新插入的实例⚠️ 注意事项:
- 主键字段必须正确声明(如 ID uint + gorm:"primaryKey"),且类型支持自增(如 uint, int, int64);
- 若结构体主键字段名为 Id(首字母小写),需通过 gorm:"column:id;primaryKey" 显式映射,否则 GORM 可能无法识别或回填;
- db.Create() 是推荐方式(语义明确、专用于插入);db.Save() 在记录无主键值时等效于 Create,但语义稍弱;
- 该行为依赖数据库驱动对 LastInsertId() 的支持(MySQL、PostgreSQL 的 RETURNING、SQLite 的 last_insert_rowid() 均被 GORM 封装兼容);
- 不要尝试在 Create 后立即执行 db.LastInsertId() —— GORM v1 并未暴露该方法,且非必要。
总结:GORM 的“主键回填”是开箱即用的核心特性。只要结构体定义规范、主键可写,插入后直接访问结构体主键字段即可安全、高效地获取最新 ID 或完整实体。










