Skip to content

软删除

软删除是一种不真正删除数据,而是标记为已删除的机制。这样可以保留数据历史,并支持数据恢复。

配置软删除

使用 @SoftDelete 装饰器标记软删除字段:

ts
import { Table, Column, PrimaryKey, SoftDelete } from '@ibestservices/ibest-orm';

@Table()
class Article {
  @PrimaryKey()
  id?: number;

  @Column()
  title?: string;

  @Column()
  content?: string;

  @SoftDelete()  // 默认列名 'deleted_at'
  deletedAt?: string;
}

自定义列名

ts
@SoftDelete({ name: 'delete_time' })
deleteTime?: string;

软删除操作

对配置了软删除的模型执行删除操作时,会自动使用软删除:

ts
const orm = getORM();

// 软删除(设置 deleted_at 为当前时间)
orm.query(Article).where({ id: 1 }).delete();

// 等效于:UPDATE article SET deleted_at = '2024-01-01 12:00:00' WHERE id = 1

查询行为

默认查询(自动过滤已删除)

ts
// 自动添加 WHERE deleted_at IS NULL
const articles = orm.query(Article).find();

包含已删除记录

ts
// 查询所有记录,包括已删除的
const allArticles = orm.query(Article).withTrashed().find();

只查询已删除记录

ts
// 只查询已删除的记录
const deletedArticles = orm.query(Article).onlyTrashed().find();

恢复已删除记录

ts
// 恢复单条记录
orm.query(Article).where({ id: 1 }).restore();

// 恢复多条记录
orm.query(Article).whereIn('id', [1, 2, 3]).restore();

// 等效于:UPDATE article SET deleted_at = NULL WHERE id IN (1, 2, 3)

永久删除

如果需要真正删除数据:

ts
// 先查询已删除的记录
const deleted = orm.query(Article).onlyTrashed().where({ id: 1 }).first();

// 然后使用 deleteById 永久删除
if (deleted) {
  orm.deleteById(Article, deleted.id);
}

// 或者使用 forceDelete 永久删除
orm.query(Article).where({ id: 1 }).forceDelete();

完整示例

ts
import { Table, Column, PrimaryKey, SoftDelete, CreatedAt, getORM } from '@ibestservices/ibest-orm';

@Table()
class Post {
  @PrimaryKey()
  id?: number;

  @Column()
  title?: string;

  @CreatedAt()
  createdAt?: string;

  @SoftDelete()
  deletedAt?: string;
}

const orm = getORM();

// 创建文章
const post = new Post();
post.title = '测试文章';
orm.insert(post);

// 软删除
orm.query(Post).where({ id: post.id }).delete();

// 查询(不包含已删除)
const activePosts = orm.query(Post).find();
console.log('活跃文章数:', activePosts.length);  // 0

// 查询(包含已删除)
const allPosts = orm.query(Post).withTrashed().find();
console.log('所有文章数:', allPosts.length);  // 1

// 恢复
orm.query(Post).where({ id: post.id }).restore();

// 再次查询
const restoredPosts = orm.query(Post).find();
console.log('恢复后文章数:', restoredPosts.length);  // 1

最佳实践

  1. 统一使用软删除:对于重要数据,建议统一使用软删除
  2. 定期清理:定期清理长期已删除的数据,避免数据库膨胀
  3. 索引优化:在 deleted_at 字段上建立索引,提高查询性能
  4. 关联处理:删除主表记录时,考虑关联表的处理策略