基于GORM实现软删除用法

DeleteAt
基于原生 GORM,model 中添加 gorm.DeleteAt 字段,从而自动获取 Soft-Delete 的能力。

// gorm.Model (注:在 gorm 项目的 model.go 中)
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

type UserV1 struct {
  gorm.Model
  Name string
}
// equals
type UserV2 struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
  Name string
}

原生GORM,当我们调用 Delete 时, 指定的记录并不会从数据库中物理删除,而是会将 gorm.DeleteAt 字段的值设置为当前时间,在一般情况下,调用查询方法时不会被返回。
内部适配:

// user's ID is `111`
db.Delete(&user)
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;

// Batch Delete
db.Where("age = ?", 20).Delete(&User{})
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;

// Soft deleted records will be ignored when querying
db.Where("age = 20").Find(&user)
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;

原来的 Delete 调用会被转换为一次 Update,自动处理了 delete_at 字段的更新逻辑。查询的时候,如果发现 model 中包含 gorm.DeleteAt 字段,也会自动加上 deleted_at IS NULL 作为 Where 条件。
如果需要查询到已经被软删除的记录,在 GORM 查询时加上 Unscoped

db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;

扩展库

  • DeletedAt (timestamp): NULL vs DeletedTimestamp
  • DeletedAt (int64): 0 vs DetetedUnixTime
  • IsDel (bool): 0 vs 1
  • IsDel (bool) + DelTime (timestamp): 0 vs 1

原生的软删除支持的类型仅为 sql.NullTime,对应到第一种。
替换类型从 gorm.DeleteAt 换成 soft_delete.DeleteAt:

import "gorm.io/plugin/soft_delete"

type User struct {
  ID        uint
  Name      string                `gorm:"uniqueIndex:udx_name"`
  DeletedAt soft_delete.DeletedAt `gorm:"uniqueIndex:udx_name"`
}

Unix second
DeletedAt soft_delete.DeletedAt 默认按照 unix 时间戳来判断,对应到第二种
时间戳支持秒、毫秒、纳秒,通过 softDelete tag 来指明:gorm:"softDelete:xx"

type User struct {
  ID    uint
  Name  string
  DeletedAt soft_delete.DeletedAt `gorm:"softDelete:milli"`
  // DeletedAt soft_delete.DeletedAt `gorm:"softDelete:nano"`
}
// Query
SELECT * FROM users WHERE deleted_at = 0;

// Delete
UPDATE users SET deleted_at = /* current unix milli second or nano second */ WHERE ID = 1;

0/1 flag
对应第三种模式,使用 0 / 1 进行标识,只需要将 gorm:"softDelete:xxxx" 中的值,从上面时间戳的 milli/nano 替换为 flag 。

import "gorm.io/plugin/soft_delete"

type User struct {
  ID    uint
  Name  string
  IsDel soft_delete.DeletedAt `gorm:"softDelete:flag"`
}

// Query
SELECT * FROM users WHERE is_del = 0;

// Delete
UPDATE users SET is_del = 1 WHERE ID = 1;

混合模式
对应第四种,一般情况不推荐使用。需要两个字段,一个承载 flag 的能力,一个承载时间戳。 可以通过 gorm 的 tag 来适配。

type User struct {
  ID        uint
  Name      string
  DeletedAt time.Time
  IsDel     soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // use `1` `0`
  // IsDel     soft_delete.DeletedAt `gorm:"softDelete:,DeletedAtField:DeletedAt"` // use `unix second`
  // IsDel     soft_delete.DeletedAt `gorm:"softDelete:nano,DeletedAtField:DeletedAt"` // use `unix nano second`
}

// Query
SELECT * FROM users WHERE is_del = 0;

// Delete
UPDATE users SET is_del = 1, deleted_at = /* current unix second */ WHERE ID = 1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值