gorm 删除——迹忆客-ag捕鱼王app官网
删除一条记录
删除一条记录时,删除对象需要指定主键,否则会触发 批量 delete,例如:
// email 的 id 是 `10`
db.delete(&email)
// delete from emails where id = 10;
// 带额外条件的删除
db.where("name = ?", "jinzhu").delete(&email)
// delete from emails where id = 10 and name = "jinzhu";
根据主键删除
gorm 允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字(如以下例子。也可以使用字符串——译者注)。查看 查询-内联条件(query inline conditions) 了解详情。
db.delete(&user{}, 10)
// delete from users where id = 10;
db.delete(&user{}, "10")
// delete from users where id = 10;
db.delete(&users, []int{1,2,3})
// delete from users where id in (1,2,3);
delete hook
对于删除操作,gorm 支持 beforedelete、afterdelete hook,在删除记录时会调用这些方法,查看 hook 获取详情
func (u *user) beforedelete(tx *gorm.db) (err error) {
if u.role == "admin" {
return errors.new("admin user not allowed to delete")
}
return
}
批量删除
如果指定的值不包括主属性,那么 gorm 会执行批量删除,它将删除所有匹配的记录
db.where("email like ?", "%jinzhu%").delete(&email{})
// delete from emails where email like "%jinzhu%";
db.delete(&email{}, "email like ?", "%jinzhu%")
// delete from emails where email like "%jinzhu%";
阻止全局删除
如果在没有任何条件的情况下执行批量删除,gorm 不会执行该操作,并返回 errmissingwhereclause
错误
对此,你必须加一些条件,或者使用原生 sql,或者启用 allowglobalupdate
模式,例如:
db.delete(&user{}).error // gorm.errmissingwhereclause
db.where("1 = 1").delete(&user{})
// delete from `users` where 1=1
db.exec("delete from users")
// delete from users
db.session(&gorm.session{allowglobalupdate: true}).delete(&user{})
// delete from users
返回删除行的数据
返回被删除的数据,仅适用于支持 returning 的数据库,例如:
// 返回所有列
var users []user
db.clauses(clause.returning{}).where("role = ?", "admin").delete(&users)
// delete from `users` where role = "admin" returning *
// users => []user{{id: 1, name: "jinzhu", role: "admin", salary: 100}, {id: 2, name: "jinzhu.2", role: "admin", salary: 1000}}
// 返回指定的列
db.clauses(clause.returning{columns: []clause.column{{name: "name"}, {name: "salary"}}}).where("role = ?", "admin").delete(&users)
// delete from `users` where role = "admin" returning `name`, `salary`
// users => []user{{id: 0, name: "jinzhu", role: "", salary: 100}, {id: 0, name: "jinzhu.2", role: "", salary: 1000}}
软删除
如果我们的模型包含了一个 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;
永久删除
我们也可以使用 unscoped
永久删除匹配的记录
db.unscoped().delete(&order)
// delete from orders where id=10;
delete flag
默认情况下,gorm.model
使用 *time.time
作为 deletedat 字段的值。此外,通过 gorm.io/plugin/soft_delete
插件还支持其它数据格式。
提示 当使用 deletedat 字段创建唯一复合索引时,你必须通过
gorm.io/plugin/soft_delete
等插件将字段定义为时间戳之类的数据格式,例如: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 时间戳
将 unix 秒级时间戳作为 delete flag
import "gorm.io/plugin/soft_delete"
type user struct {
id uint
name string
deletedat soft_delete.deletedat
}
// 查询
select * from users where deleted_at = 0;
// 删除
update users set deleted_at = /* 当前时间戳 */ where id = 1;
你还可以指定 milli、nano 使用毫秒、纳秒作为值,例如:
type user struct {
id uint
name string
deletedat soft_delete.deletedat `gorm:"softdelete:milli"`
// deletedat soft_delete.deletedat `gorm:"softdelete:nano"`
}
// 查询
select * from users where deleted_at = 0;
// 删除
update users set deleted_at = /* 当前毫秒、纳秒时间戳 */ where id = 1;
使用 1 / 0 作为 delete flag
import "gorm.io/plugin/soft_delete"
type user struct {
id uint
name string
isdel soft_delete.deletedat `gorm:"softdelete:flag"`
}
// 查询
select * from users where is_del = 0;
// 删除
update users set is_del = 1 where id = 1;
混合模式
混合模式可以使用 0, 1 或 unix 秒来标识数据是否已被删除,并同时保存删除的时间。
type user struct {
id uint
name string
deletedat time.time
isdel soft_delete.deletedat `gorm:"softdelete:flag,deletedatfield:deletedat"` // 使用 `1` `0` 标识
// isdel soft_delete.deletedat `gorm:"softdelete:,deletedatfield:deletedat"` // 使用 `unix second` 标识
// isdel soft_delete.deletedat `gorm:"softdelete:nano,deletedatfield:deletedat"` // 使用 `unix nano second` 标识
}
// 查询
select * from users where is_del = 0;
// 删除
update users set is_del = 1, deleted_at = /* current unix second */ where id = 1;