GROM Create和Save的区别
一个单词引起的线上bug。
var record Record
orm.Order("id desc").First(&record, "id = ?", id).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
record.Path = "/login"
}
record.RequestTime = time.Now()
err = e.Orm.Create(&record).Error
if err != nil {
return err
}
上述代码,由于不了解Create、Save的差异,导致使用了Create, 导致插入失败。
用AI总结了以下两者的差异
在 GORM 中,Create 和 Save 都是用来将数据写入数据库的方法,但它们有一些关键区别,特别是在处理主键、更新行为方面。
✅ 简明对比:Create vs Save
| 特性 | Create |
Save |
|---|---|---|
| 主键(ID)是否存在 | 假设是新记录,只插入 | 如果主键存在,则更新,否则插入 |
| 是否执行更新 | ❌ 不更新已有记录 | ✅ 更新已有记录(通过主键) |
| 常用于 | 新增数据 | 新增或更新(Upsert) |
| 主键为 0/空时 | 自动填充主键(如自增 ID) | 会当作新记录插入 |
| 操作方式 | INSERT |
INSERT 或 UPDATE(取决于是否有主键) |
🧪 示例演示:
🔸 Create 示例:
user := User{Name: "Alice", Age: 30}
db.Create(&user)
- 只会执行
INSERT INTO users ...。 - 即使数据库中已有主键相同的数据,也不会更新(会报错或者插入失败)。
🔸 Save 示例:
user := User{ID: 1, Name: "Bob", Age: 25}
db.Save(&user)
- 如果 ID=1 的用户已经存在,就会执行
UPDATE。 - 如果 ID=1 的用户不存在,就会执行
INSERT。
💡 实际使用建议:
- 如果你 确定是在新增记录,用
Create更安全。 - 如果你需要 根据主键来判断是插入还是更新,用
Save。 - 如果你需要根据某个字段是否存在来 upsert,可以用:
db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&user)
✅ 总结一句话:
Create 是只插入,Save 是插入或更新(取决于主键是否存在)。

浙公网安备 33010602011771号