Save

在 GORM 中,Save 方法默认是根据主键来执行更新或创建操作的。如果对象包含主键,Save 会更新对应的记录;如果对象不包含主键,Save 会创建新的记录。

也就是说,Save 方法并不能直接与 Where 方法结合使用来实现 “找到了就更新,找不到就创建” 的逻辑。因为 Save 方法在执行时并不会考虑 Where 方法设定的条件。

如果你想实现 “找到了就更新,找不到就创建” 的逻辑,你可以使用 FirstOrCreateFirstOrInit 方法。这两个方法会先尝试根据指定的条件查找记录,如果找到了就返回该记录,如果没找到就创建(对于 FirstOrCreate)或初始化(对于 FirstOrInit)一个新的对象。

FirstOrCreateFirstOrInit

  • FirstOrInit 方法会先尝试根据指定的条件查找记录,如果找到了就返回该记录,如果没找到就初始化一个新的对象,但不会在数据库中创建新的记录。
  • FirstOrCreate 方法也会先尝试根据指定的条件查找记录,如果找到了就返回该记录,如果没找到就在数据库中创建一个新的记录,并返回这个新创建的记录。
    因此,如果你只是想初始化一个新的对象而不想在数据库中创建新的记录,你应该使用 FirstOrInit 方法。如果你想在数据库中创建新的记录,你应该使用 FirstOrCreate 方法。

Assign

在 GORM 中,Assign 方法用于在查找或初始化一个新的对象时,为其分配或更新一些字段的值。这个方法在使用 FirstOrInitFirstOrCreate 方法时非常有用。

Assign 方法会在 FirstOrInitFirstOrCreate 方法找到记录时更新指定的字段,而不是全部字段。如果 FirstOrInitFirstOrCreate 方法没有找到记录,Assign 方法会为新创建或初始化的对象分配指定的字段的值。

在 GORM 中,如果你使用 FirstOrCreate 方法并结合 Assign 方法,那么在创建新记录时,Assign 方法指定的字段会被赋予相应的值。对于没有被 Assign 方法覆盖的字段,它们的值将是其数据类型的零值

例如,数值类型的字段将被设置为0; 字符串类型的字段将被设置为空字符串; 如果它们是可空字段 ‘例如,指针类型或 sql.NullString 类型’ ,并且你没有为它们指定值,那么它们的值将是 nil 或等效于 NULL 的值, 如果你想在创建新记录时为这些可空字段指定非 nil 或非 NULL 的值,你可以在 Assign 方法中包含这些字段。

Attrs

在 GORM 中,AttrsAssign 都是用于在查找或初始化一个新的对象时,为其分配或更新一些字段的值的方法。这两个方法在使用 FirstOrInitFirstOrCreate 方法时非常有用。然而,它们的行为有所不同。

  • Attrs 方法在 FirstOrInitFirstOrCreate 方法找不到记录时,会为新创建或初始化的对象分配指定的字段的值。如果 FirstOrInitFirstOrCreate 方法找到了记录,Attrs 方法指定的字段将被忽略。

  • Assign 方法无论 FirstOrInitFirstOrCreate 方法是否找到记录,都会更新或分配指定的字段的值。