将gorm.Model改为自定义Model

我相信有很多人都想把

type Model struct {
   ID        uint `gorm:"primary_key"`
   CreatedAt time.Time
   UpdatedAt time.Time
   DeletedAt *time.Time `sql:"index"`
}

把时间类型改为字符串或者int64来记录时间  弄了几次数据库DeletedAt保存的空串导致失败(原因在于DeletedAt必须定义指针类型,这样创建的时候就不会往数据库插入空串),下面以string写示例

type Model struct {
   ID        uint    `gorm:"primary_key" json:"id"`
   CreatedAt string  `json:"created_at"`
   UpdatedAt string  `json:"updated_at"`
   DeletedAt *string `gorm:"default:null;index:dbc" json:"deleted_at"`
}
根据gorm提供的db.Callback().Create().Replae("gorm:create", newCreateFunction)替换gorm原有的回调方法,我们可以全局搜索DefaultCallback就会找到gorm原有的回调方法,其中create、update、delete与时间相关的都要替换。

将gorm.Model改为自定义Model_第1张图片

将gorm.Model改为自定义Model_第2张图片

将gorm.Model改为自定义Model_第3张图片

下面我们进行方法替换

db.Callback().Create().Replace("gorm:update_time_stamp",updateTimeStampForCreateCallback)
db.Callback().Update().Replace("gorm:update_time_stamp",updateTimeStampForUpdateCallback)
db.Callback().Delete().Replace("gorm:delete", deleteCallback)

//将gorm自带回调方法copy出来进行修改

func updateStampForCreateCallback(scope *gorm.Scope) {

   if !scope.HasError() {
//此处时间如果是int64就修改time.Now().Unix()就行了
      nowTime := time.Now().Format("2006-01-02 15:04:05")
      if createTimeField, ok := scope.FieldByName("CreatedAt"); ok {
         if createTimeField.IsBlank {
            createTimeField.Set(nowTime)
         }
      }

      if modifyTimeField, ok := scope.FieldByName("UpdatedAt"); ok {
         if modifyTimeField.IsBlank {
            modifyTimeField.Set(nowTime)
         }
      }
   }
}

func updateTimeStampForUpdateCallback(scope *gorm.Scope) {
   if _, ok := scope.Get("gorm:update_column"); !ok {
//此处时间如果是int64就修改time.Now().Unix()就行了
      scope.SetColumn("UpdatedAt", time.Now().Format("2006-01-02 15:04:05"))
   }
}

func deleteCallback(scope *gorm.Scope) {
   if !scope.HasError() {
      var extraOption string
      if str, ok := scope.Get("gorm:delete_option"); ok {
         extraOption = fmt.Sprint(str)
      }

      deletedOnField, hasDeletedOnField := scope.FieldByName("DeletedAt")

      if !scope.Search.Unscoped && hasDeletedOnField {
         scope.Raw(fmt.Sprintf(
            "UPDATE %v SET %v=%v%v%v",
            scope.QuotedTableName(),
            scope.Quote(deletedOnField.DBName),
//此处时间如果是int64就修改time.Now().Unix()就行了
            scope.AddToVars(time.Now().Format("2006-01-02 15:04:05")),
            addExtraSpaceIfExist(scope.CombinedConditionSql()),
            addExtraSpaceIfExist(extraOption),
         )).Exec()
      } else {
         scope.Raw(fmt.Sprintf(
            "DELETE FROM %v%v%v",
            scope.QuotedTableName(),
            addExtraSpaceIfExist(scope.CombinedConditionSql()),
            addExtraSpaceIfExist(extraOption),
         )).Exec()
      }
   }
}
func addExtraSpaceIfExist(str string) string {
   if str != "" {
      return " " + str
   }
   return ""
}

到此结束希望对大家有所帮助,我也被这里折磨了好久

你可能感兴趣的:(将gorm.Model改为自定义Model)