Save方法在没有pk的时候是insert,有pk的时候是update,当update时,如果Error == nil && RowsAffected == 0,则先select,如果result.RecordNotFound() == true则insert,如果Error == nil则update。
// Save update value in database, if the value doesn't have primary key, will insert itfunc (s *DB) Save(value interface{}) *DB {scope := s.NewScope(value)if !scope.PrimaryKeyZero() {newDB := scope.callCallbacks(s.parent.callbacks.updates).dbif newDB.Error == nil && newDB.RowsAffected == 0 {return s.New().Table(scope.TableName()).FirstOrCreate(value)}return newDB}return scope.callCallbacks(s.parent.callbacks.creates).db}
// FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)// https://jinzhu.github.io/gorm/crud.html#firstorcreatefunc (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {c := s.clone()if result := s.First(out, where...); result.Error != nil {if !result.RecordNotFound() {return result}return c.NewScope(out).inlineCondition(where...).initialize().callCallbacks(c.parent.callbacks.creates).db} else if len(c.search.assignAttrs) > 0 {return c.NewScope(out).InstanceSet("gorm:update_interface", c.search.assignAttrs).callCallbacks(c.parent.callbacks.updates).db}return c}
