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时,就会将该字段的值更新。