go gorm 软删除和查询 及注意事项
软删除
如果您的模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力!
拥有软删除能力的模型调用 Delete 时,记录不会从数据库中被真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过普通的查询方法找到该记录。
// user 的 ID 是 `111` db.Delete(&user) // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111; // 批量删除 db.Where("age = ?", 20).Delete(&User{}) // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20; // 在查询时会忽略被软删除的记录 db.Where("age = 20").Find(&user) // SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
如果您不想引入 gorm.Model,您也可以这样启用软删除特性:
type User struct { ID int Deleted gorm.DeletedAt Name string }
查找被软删除的记录
您可以使用 Unscoped 找到被软删除的记录
db.Unscoped().Where("age = 20").Find(&users) // SELECT * FROM users WHERE age = 20;
但是scan是可以查询该记录的
scan无视DeletedAt db.Where("age = 20").Scan(&users) // SELECT * FROM users WHERE age = 20;
永久删除
您也可以使用 Unscoped 永久删除匹配的记录
db.Unscoped().Delete(&order) // DELETE FROM orders WHERE id=10;
使用删除标记
type User struct { ID uint Name string DeletedAt time.Time IsDelete 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` }
注意事项
1、如果查询是用的是table,返回的是dto,及table里的结构体与扫描到的结构体不一致,则扫描到的结构体如dto结构体里也必须包含is_delete字段,否则不会带is_delete查询,如下
var user []dto.User orm.Orm.Table(model.User{}.TableName()).Debug().Find(&user) type User struct { Id string `json:"id" gorm:"column:id;primary_key;"` // id IsDelete soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` //dto 必须有,否则不会带is_delete查询 DeletedAt time.Time }