使用 GORM 进行软删除和硬删除

发布时间 2023-07-11 11:06:56作者: 若-飞

目录结构:

  • 软删除
    • 在 GORM 中使用软删除
    • 删除已经被标记为已删除的记录
  • 硬删除
    • 在 GORM 中使用硬删除
    • 永久删除已经被标记为已删除的记录

软删除

在 GORM 中,软删除(soft delete)是指将记录标记为已删除,而不是从数据库中永久删除记录。软删除可以保留已删除记录的历史记录,同时避免意外删除记录。在 GORM 中,您可以使用 DeletedAt 字段来实现软删除。如果您在模型中定义了 DeletedAt 字段,GORM 会自动为您添加一个软删除过滤器,使查询不包括已被标记为已删除的记录。如果您想要查询已经被标记为已删除的记录,或者执行硬删除,您可以使用 Unscoped方法来移除软删除过滤器。

在 GORM 中使用软删除

在 GORM 中,使用软删除非常简单。只需要在模型中定义一个 DeletedAt 字段即可。下面是一个示例:

go
type User struct {
    gorm.Model
    Name      string
    Email     string
    DeletedAt gorm.DeletedAt // 软删除
}

在这个示例中,我们在 User 模型中定义了一个 DeletedAt 字段。这将自动为模型添加软删除过滤器,并将查询中不包括已被标记为已删除的记录。

删除已经被标记为已删除的记录

如果您想要删除已经被标记为已删除的记录,您可以使用以下代码:

go
func (r *UserRepository) DeleteSoftDeletedByID(id uint) error {
    result := r.db.Unscoped().Delete(&User{}, id)
    if result.Error != nil {
        return result.Error
    }
    if result.RowsAffected == 0 {
        return gorm.ErrRecordNotFound
    }
    return nil
}

在这个方法中,我们使用 Unscoped 方法来移除软删除过滤器,并使用 Delete 方法来删除记录。这将永久删除记录,而不是标记记录为已删除。

对应的 SQL 语句如下:

sql
UPDATE `users` SET `deleted_at`='2023-07-11 12:00:00' WHERE `users`.`deleted_at` IS NULL AND `id` IN (?, ?, ?)

这个 SQL 语句会永久删除 users 表中 id 为 1 的记录。

硬删除

在某些情况下,您可能需要完全删除记录,而不是标记记录为已删除。这种情况下,您可以使用硬删除(hard delete)。在 GORM 中,您可以使用 Unscoped 方法来永久删除已经被标记为已删除的记录。

在 GORM 中使用硬删除

在 GORM 中,使用硬删除也非常简单。只需要在查询中使用 Unscoped 方法就可以永久删除已经被标记为已删除的记录。下面是一个示例:

go
func (r *UserRepository) DeleteHardDeletedByID(id uint) error {
    result := r.db.Unscoped().Delete(&User{}, id)
    if result.Error != nil {
        return result.Error
    }
    if result.RowsAffected == 0 {
        return gorm.ErrRecordNotFound
    }
    return nil
}

在这个方法中,我们使用 Unscoped 方法来移除软删除过滤器,并使用 Delete 方法来永久删除记录。

对应的 SQL 语句如下:

sql
DELETE FROM `users` WHERE `users`.`id` = 1

这个 SQL 语句会删除 users 表中 id 为 1 的记录。

总结:

通过使用 GORM 中的软删除和硬删除特性,您可以有效地管理数据库中的记录。软删除可以让您标记记录为已删除,同时保留记录的历史记录,避免意外删除记录。而硬删除则可以完全删除记录,如果您需要彻底清除记录,硬删除是一个很好的选择。

需要注意的是,软删除并不是所有情况下都适用。如果您的应用程序需要满足 GDPR、HIPAA 或其他法律法规的要求,您可能需要永久删除某些记录。此外,在某些情况下,软删除可能会影响查询性能,因为查询需要过滤已经被标记为已删除的记录。

因此,在使用软删除和硬删除时,请根据您的应用程序的特定需求,进行相应的选择和配置。