gorm反对对model中的工夫字段进行默认操作:

  • CreatedAt:创立工夫
  • UpdatedAt:更新工夫
  • DeletedAt: 删除工夫

也就是说,若model中含有上述字段,在CRUD操作时,gorm会自动更新上述的工夫字段的值为now()。

删除的时候

删除的callbacks:

// github.com/jinzhu/gorm/callback_delete.go// Define callbacks for deletingfunc init() {   ......   DefaultCallback.Delete().Register("gorm:delete", deleteCallback)   ......}

在deleteCallback中,依据model中是否有DeletedAt字段,决定是执行update还是delete:

// deleteCallback used to delete data from database or set deleted_at to current time (when using with soft delete)func deleteCallback(scope *Scope) {   if !scope.HasError() {      var extraOption string      if str, ok := scope.Get("gorm:delete_option"); ok {         extraOption = fmt.Sprint(str)      }      //查找DeletedAt字段      deletedAtField, hasDeletedAtField := scope.FieldByName("DeletedAt")      if !scope.Search.Unscoped && hasDeletedAtField {    //model struct中有DeletedAt字段         scope.Raw(fmt.Sprintf(            "UPDATE %v SET %v=%v%v%v",                    //执行update-sql            scope.QuotedTableName(),            scope.Quote(deletedAtField.DBName),           //将 UpdateAt对应的db字段更新为now()            scope.AddToVars(scope.db.nowFunc()),            addExtraSpaceIfExist(scope.CombinedConditionSql()),            addExtraSpaceIfExist(extraOption),         )).Exec()      } else {         scope.Raw(fmt.Sprintf(            "DELETE FROM %v%v%v",                    //model struct中没有DeletedAt字段, 执行delete-sql            scope.QuotedTableName(),            addExtraSpaceIfExist(scope.CombinedConditionSql()),            addExtraSpaceIfExist(extraOption),         )).Exec()      }   }}

插入的时候

插入的callbacks:

// github.com/jinzhu/gorm/callback_create.go// Define callbacks for creatingfunc init() {   ......   DefaultCallback.Create().Register("gorm:update_time_stamp", updateTimeStampForCreateCallback)   DefaultCallback.Create().Register("gorm:create", createCallback)   ......}

在updateTimeStampForCreateCallback 这个callback,进行了工夫字段的解决:

  • 查找value中是否有CreatedAt和UpdatedAt字段;
  • 若有,将其值设置为now();
// updateTimeStampForCreateCallback will set `CreatedAt`, `UpdatedAt` when creatingfunc updateTimeStampForCreateCallback(scope *Scope) {   if !scope.HasError() {      now := scope.db.nowFunc()      if createdAtField, ok := scope.FieldByName("CreatedAt"); ok {         if createdAtField.IsBlank {            createdAtField.Set(now)         }      }      if updatedAtField, ok := scope.FieldByName("UpdatedAt"); ok {         if updatedAtField.IsBlank {            updatedAtField.Set(now)         }      }   }}

前面在createCallback执行insert-sql时,就会将该字段的值插入进去。

更新的时候

更新的callbacks:

// github.com/jinzhu/gorm/callback_update.go// Define callbacks for updatingfunc init() {   ......   DefaultCallback.Update().Register("gorm:update_time_stamp", updateTimeStampForUpdateCallback)   DefaultCallback.Update().Register("gorm:update", updateCallback)   ......}

在updateTimeStampForUpdateCallback这个callback,进行了工夫字段的解决:将model-struct中UpdatedAt这个字段的值,赋值为now()。

// updateTimeStampForUpdateCallback will set `UpdatedAt` when updatingfunc updateTimeStampForUpdateCallback(scope *Scope) {   if _, ok := scope.Get("gorm:update_column"); !ok {      scope.SetColumn("UpdatedAt", scope.db.nowFunc())   }}

前面在updateCallback执行update-sql时,就会将该字段的值更新。