irpas技术客

基于GORM实现软删除用法_gorm 软删除_羡鱼°

网络投稿 3508

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 DeletedTimestampDeletedAt (int64): 0 vs DetetedUnixTimeIsDel (bool): 0 vs 1IsDel (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;


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #gorm #软删除 #DeleteAt基于原生 #gormModel #中添加 #gormDeleteAt #字段从而自动获取 #SoftDelete