gorm软删除_【Go】gin Blog项目(八) GORM Callbacks 及拓展

本来应该写Docker的,但是想了下,还是决定先做好开发,最后部署Docker。

这里先提出问题,我们models目录下的 tag.go、 article.go 文件,它们有两个方法:AfterCreate、AfterUpdate。

每个文件都要实现这两个办法?

目标

通过GORM的 Callbacks 来实现功能,不需要编写每个文件。

功能

每次 create 更新 CreatedOn 字段。

每次 update 更新 ModifiedOn 字段。

实现Callbacks

参考文档还是 gorm.io .

参考地址1:https://gorm.io/zh_CN/docs/write_plugins.html

参考地址2:https://gorm.io/docs/update.html#Change-Updating-Values

参考地址3:https://github.com/go-gorm/gorm/issues/3441

参考地址4:https://gorm.io/zh_CN/docs/hooks.html

这里我们需要针对 before_create 和 before_update 两个Callback实现

在models/models.go 文件中增加两个函数:

models/models.go

Go

func updateTimeStampForBeforeCreateCallback(db *gorm.DB) {

db.Statement.SetColumn("CreatedOn", time.Now().Unix())

}

func updateTimeStampForBeforeUpdateCallback(db *gorm.DB) {

db.Statement.SetColumn("ModifiedOn", time.Now().Unix())

}

1

2

3

4

5

6

7

funcupdateTimeStampForBeforeCreateCallback(db *gorm.DB){

db.Statement.SetColumn("CreatedOn",time.Now().Unix())

}

funcupdateTimeStampForBeforeUpdateCallback(db *gorm.DB){

db.Statement.SetColumn("ModifiedOn",time.Now().Unix())

}

SetColumn函数实际上是GORM包实现的一个辅助函数,内容如下:

Go

// Helpers

// SetColumn set column's value

func (stmt *Statement) SetColumn(name string, value interface{}) {

if v, ok := stmt.Dest.(map[string]interface{}); ok {

v[name] = value

} else if stmt.Schema != nil {

if field := stmt.Schema.LookUpField(name); field != nil {

switch stmt.ReflectValue.Kind() {

case reflect.Slice, reflect.Array:

field.Set(stmt.ReflectValue.Index(stmt.CurDestIndex), value)

case reflect.Struct:

field.Set(stmt.ReflectValue, value)

}

} else {

stmt.AddError(ErrInvalidField)

}

} else {

stmt.AddError(ErrInvalidField)

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// Helpers

// SetColumn set column's value

func(stmt *Statement)SetColumn(namestring,valueinterface{}){

ifv,ok:=stmt.Dest.(map[string]interface{});ok{

v[name]=value

}elseifstmt.Schema!=nil{

iffield:=stmt.Schema.LookUpField(name);field!=nil{

switchstmt.ReflectValue.Kind(){

casereflect.Slice,reflect.Array:

field.Set(stmt.ReflectValue.Index(stmt.CurDestIndex),value)

casereflect.Struct:

field.Set(stmt.ReflectValue,value)

}

}else{

stmt.AddError(ErrInvalidField)

}

}else{

stmt.AddError(ErrInvalidField)

}

}

注册Callback

在 models.go 的 init 函数中增加以下语句:

Go

// 用新函数替换GORM Create、Update流程自带的回调函数

db.Callback().Create().Replace("gorm:before_create", updateTimeStampForBeforeCreateCallback)

db.Callback().Update().Replace("gorm:before_update", updateTimeStampForBeforeUpdateCallback)

1

2

3

// 用新函数替换GORM Create、Update流程自带的回调函数

db.Callback().Create().Replace("gorm:before_create",updateTimeStampForBeforeCreateCallback)

db.Callback().Update().Replace("gorm:before_update",updateTimeStampForBeforeUpdateCallback)

验证

访问AddTag接口,成功之后检查数据库,可以发现 created_on 字段为当前执行时间。

访问EditTag接口,可发现 modified_on 为最后一次执行更新的实际。

拓展

P.S. 其实我们实现的 CreatedOn、 ModifiedOn 以及这里要实现的 DeletedOn 都是GORM已经实现好的。

实际项目中,硬删除是比较少的,那么是否可以通过Callbacks来完成这个功能呢。

我们在先前 Model struct 增加 DeletedOn 变量。

models/models.go

Go

//Model ...

type Model struct {

ID uint `gorm:"primarykey" json:"id"`

CreatedOn int `json:"created_on"`

ModifiedOn int `json:"modified_on"`

DeletedOn int `json:"deleted_on"`

}

1

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值