Laravel软删除通过添加deleted_at字段标记删除状态,实现数据可恢复;需在迁移中添加softDeletes()并引入SoftDeletes Trait;查询默认忽略软删除数据,可用withTrashed()或onlyTrashed()获取全部或仅软删除记录;恢复用restore(),永久删除用forceDelete();注意唯一约束冲突、关联模型处理及数据合规性问题。

Laravel的软删除,简单来说,就是一种“假删除”机制。它不会真的从数据库里把数据抹掉,而是给记录打上一个“已删除”的标记。具体实现上,就是在你的数据库表里加一个
deleted_at
SoftDeletes
要实现Laravel模型的软删除,你主要需要做两件事:更新数据库结构和修改对应的模型。
首先,你需要为你的数据表添加一个
deleted_at
TIMESTAMP
NULL
Schema::table('your_table_name', function (Blueprint $table) {
$table->softDeletes(); // 这会添加一个 nullable timestamp 类型的 deleted_at 字段
});如果你是在创建新表,也可以直接在
create
Schema::create('your_table_name', function (Blueprint $table) {
$table->id();
// ... 其他字段
$table->softDeletes(); // 添加 deleted_at 字段
$table->timestamps();
});运行完迁移(
php artisan migrate
接着,你需要告诉Laravel你的模型要使用软删除功能。这通过在模型中引入
Illuminate\Database\Eloquent\SoftDeletes
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // 引入 SoftDeletes Trait
class YourModelName extends Model
{
use HasFactory, SoftDeletes; // 在这里使用它
// ... 你的其他模型配置
}现在,当你对
YourModelName
delete()
DELETE FROM ...
deleted_at
默认情况下,所有通过Eloquent查询
YourModelName
deleted_at
NULL
这两种删除方式,核心差异在于数据是否真的从数据库中消失。硬删除(或者叫永久删除)就像是把文件彻底粉碎,不留痕迹;而软删除则更像是把文件移到了回收站,虽然看不见了,但它还在那里,随时可以恢复。
硬删除:
软删除:
在我看来,除非有明确的理由必须硬删除,我通常会倾向于使用软删除。它提供了一个很好的安全网,很多时候能避免一些不必要的麻烦。想想看,如果一个用户不小心删除了他们辛苦编辑的文章,你却告诉他们“抱歉,数据没了”,这体验得多糟糕?软删除能很好地解决这类问题。当然,这也会带来一些小小的“代价”,比如数据库体积可能会略微增大,或者在处理唯一约束时需要多考虑一步。
一旦你的模型启用了软删除,Laravel提供了一套非常直观的方法来管理这些“已删除”的记录。
1. 查询软删除的数据:
默认情况下,所有Eloquent查询都会自动排除软删除的记录。如果你想查询包含软删除记录的所有数据,或者只查询软删除的记录,你需要使用特定的方法。
查询所有(包括软删除和未删除):
use App\Models\YourModelName;
$allRecords = YourModelName::withTrashed()->get();
// 比如:$posts = Post::withTrashed()->where('user_id', 1)->get();withTrashed()
deleted_at
NULL
只查询软删除的记录:
use App\Models\YourModelName; $onlyTrashedRecords = YourModelName::onlyTrashed()->get(); // 比如:$deletedUsers = User::onlyTrashed()->get();
onlyTrashed()
deleted_at
NULL
2. 恢复软删除的数据:
恢复操作同样简单,直接对一个软删除的模型实例调用
restore()
use App\Models\YourModelName;
// 假设我们有一个被软删除的记录
$deletedRecord = YourModelName::onlyTrashed()->find(1); // 找到ID为1的软删除记录
if ($deletedRecord) {
$deletedRecord->restore(); // 这会将 deleted_at 字段设置为 NULL
// 现在 $deletedRecord 已经恢复,可以通过常规查询找到
}
// 你也可以批量恢复
YourModelName::withTrashed()->where('status', 'pending')->restore();restore()
deleted_at
NULL
3. 永久删除(硬删除)数据:
如果你真的想彻底移除一条记录,即使它启用了软删除,你也可以使用
forceDelete()
use App\Models\YourModelName;
// 假设我们要彻底删除一个记录
$recordToForceDelete = YourModelName::find(1); // 找到一个未删除的记录
if ($recordToForceDelete) {
$recordToForceDelete->forceDelete(); // 永久删除,不经过软删除流程
}
// 或者,如果你想永久删除一个已经被软删除的记录
$softDeletedRecord = YourModelName::onlyTrashed()->find(2);
if ($softDeletedRecord) {
$softDeletedRecord->forceDelete(); // 永久删除
}
// 批量永久删除软删除的记录
YourModelName::onlyTrashed()->where('created_at', '<', now()->subMonths(6))->forceDelete();forceDelete()
DELETE
forceDelete()
软删除虽然好用,但也不是万能的,它有一些自己的“脾气”和需要注意的地方。
1. 唯一约束(Unique Constraints)的问题: 这是一个我个人踩过几次坑的地方。当你在数据库表中设置了唯一约束(比如用户邮箱
解决方案: 你需要在数据库迁移中,为
deleted_at
// 在你的验证规则中
'email' => [
'required',
'email',
Rule::unique('users')->where(function ($query) {
return $query->whereNull('deleted_at'); // 只有当 deleted_at 为 NULL 时才检查唯一性
}),
],或者,更直接一点,你可以在数据库层面创建复合唯一索引,将
deleted_at
deleted_at
2. 性能考量: 软删除会给你的查询语句增加一个
WHERE deleted_at IS NULL
deleted_at
withTrashed()
deleted_at
3. 关联关系(Relationships)的处理: 软删除一个父模型时,它的子模型并不会自动被软删除。例如,你软删除了一篇文章(Post),但与这篇文章关联的评论(Comments)并不会自动被软删除。这可能会导致“孤儿”数据,或者在查询时出现不一致。
解决方案:
手动处理:在父模型的
deleting
// 在 Post 模型中
protected static function boot()
{
parent::boot();
static::deleting(function($post) {
$post->comments()->each(function($comment) {
$comment->delete(); // 软删除所有关联评论
});
});
static::restoring(function($post) {
$post->comments()->withTrashed()->each(function($comment) {
$comment->restore(); // 恢复所有关联评论
});
});
}数据库级联删除:这通常用于硬删除,但如果你真的需要,也可以考虑,但软删除的场景下不太推荐。
业务逻辑判断:在查询子模型时,总是确保父模型未被软删除。
4. 数据存储与合规性: 软删除的数据仍然占用数据库空间。如果你的应用需要遵守GDPR或其他数据隐私法规,要求数据在一定时间后必须被彻底删除,那么仅仅软删除是不够的。你可能需要定期运行任务,对那些已经软删除很长时间的数据执行
forceDelete()
5. 用户界面(UI)的清晰性: 如果你的应用允许用户删除内容,最好在UI上明确告知他们数据是软删除的,并且可以恢复。这能提升用户体验,避免混淆。
总的来说,软删除是一个非常实用的功能,它为数据操作提供了一个重要的缓冲层。只要我们清楚它的工作原理和潜在的“陷阱”,并采取相应的措施,它就能极大地简化我们的开发工作,并提升应用的健壮性。
以上就是Laravel模型软删除?软删除怎样实现?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号