DoctrineExtensions 项目中的 SoftDeleteable 行为扩展详解
什么是 SoftDeleteable 行为
SoftDeleteable 是 DoctrineExtensions 项目中提供的一个强大的行为扩展,它实现了数据库记录的"软删除"功能。与传统的物理删除不同,软删除通过在记录上设置删除标记(通常是时间戳字段)来逻辑删除数据,而不是真正从数据库中移除记录。
核心特性
- 智能过滤机制:所有 SELECT 查询都会自动过滤掉已软删除的记录
- DQL 支持:可以与 DQL DELETE 查询配合使用(通过 Query Hint)
- 灵活配置:支持多种映射方式(注解、属性、XML)
- 时间感知:可设置未来删除时间(timeAware 选项)
- 删除控制:可配置是否允许硬删除(hardDelete 选项)
安装与配置
基本设置
首先需要将 SoftDeleteable 过滤器添加到 Doctrine 配置中:
$config = new Doctrine\ORM\Configuration;
$config->addFilter('soft-deleteable', 'Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter');
过滤器控制
启用或禁用过滤器非常简单:
// 启用过滤器(过滤掉已软删除的记录)
$em->getFilters()->enable('soft-deleteable');
// 禁用过滤器(显示所有记录,包括已软删除的)
$em->getFilters()->disable('soft-deleteable');
重要提示:默认情况下所有过滤器都是禁用的,必须显式启用 soft-deleteable 过滤器。
实体映射示例
使用注解/属性方式
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false, hardDelete: true)]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string')]
private $title;
#[ORM\Column(name: 'deletedAt', type: 'datetime', nullable: true)]
private $deletedAt;
// Getter和Setter方法...
}
配置选项说明
fieldName
:用于标记删除状态的字段名(必须为可空类型)timeAware
:是否启用时间感知功能(可设置未来删除时间)hardDelete
:是否允许硬删除(默认true,设为false则第二次删除仍为软删除)
XML 映射方式
<entity name="Article" table="articles">
<id name="id" type="integer">
<generator strategy="AUTO"/>
</id>
<field name="title" type="string" />
<field name="deletedAt" type="datetime" nullable="true" />
<gedmo:soft-deleteable
field-name="deletedAt"
time-aware="false"
hard-delete="true"
/>
</entity>
实际使用示例
// 创建新文章
$article = new Article();
$article->setTitle('测试文章');
$em->persist($article);
$em->flush();
// 软删除文章
$em->remove($article);
$em->flush();
// 默认查询不到已删除文章
$repo = $em->getRepository(Article::class);
$deletedArticle = $repo->findOneBy(['title' => '测试文章']);
// $deletedArticle 为 null
// 禁用过滤器后可查询到
$em->getFilters()->disable('soft-deleteable');
$deletedArticle = $repo->findOneBy(['title' => '测试文章']);
// $deletedArticle 现在能获取到
// 恢复已删除文章
$deletedArticle->setDeletedAt(null);
$em->persist($deletedArticle);
$em->flush();
使用 Traits 简化开发
DoctrineExtensions 提供了 Traits 来简化软删除字段的定义:
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
#[ORM\Entity]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt')]
class Article
{
use SoftDeleteableEntity;
// 其他字段和方法...
}
这个 Trait 会自动添加 $deletedAt
属性和相关方法,大大简化了代码。
最佳实践建议
- 索引优化:为 deletedAt 字段添加数据库索引以提高查询性能
- 定期清理:对于长期不用的软删除数据,建议定期物理删除
- 业务逻辑:重要业务数据建议保留软删除记录,次要数据可考虑硬删除
- 权限控制:考虑对查看已删除数据的权限进行控制
SoftDeleteable 行为扩展为数据删除提供了更灵活的解决方案,既保留了数据恢复的可能性,又保持了业务逻辑的完整性,是现代应用开发中非常有价值的功能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考