场景:满足某些 where 条件的某条记录,如果已经存在,则将这条记录的某些字段进行更新,如果不存在,则创建这条记录,同时更新指定的字段

FirstOrCreate 语句可以满足不存在则创建记录的要求,但没法继续对指定字段进行更新,如果我们想要完成 不存在即创建,然后更新指定字段 的需求,有以下几种方式:

  1. 使用多条语句,先使用 where 条件查找记录,若记录不存在,则直接创建,创建的同时指定要更新的字段值;若记录存在,直接更新
  2. 使用 FirstOrCreate,找到该条要更新的记录,然后更新字段
  3. 使用事务

下面介绍我目前发现的最佳方式:使用 FirstOrCreate 配合 assign 语句:

var db *gorm.DB
// ...init...
userModel := &UserExtraInfo{
    AppId: appId,
    UserId: userId,
    KeyName: keyName,
    Value: value,
}
err = db.Where(UserExtraInfo{
    AppId: appId,
    UserId: userId,
    KeyName: keyName,
}).Assign(map[string]interface{}{
    "value": value,
}).FirstOrCreate(&userModel).Error
default current_timestamp
type UserExtraInfo struct {
    Id int64
    AppId int32
    UserId int64
    KeyName string
    Value string
    CreateTime time.Time `gorm:"-"`
    ModifyTime time.Time `gorm:"-"`
}