NodeJS的sequelize偏执表

736 阅读2分钟

这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

偏执表

Sequelize 支持 paranoid 表的概念, 一个 paranoid 表是一个被告知删除记录时不会真正删除它的表.反而一个名为 deletedAt 的特殊列会将其值设置为该删除请求的时间戳,偏执表会执行记录的 软删除,而不是 硬删除

将模型定义为 paranoid

要定义 paranoid 模型,必须将 paranoid: true 参数传递给模型定义. Paranoid 需要时间戳才能起作用(如果传递 timestamps: false 了,paranoid 将不起作用)m可以将默认的列名(默认是 deletedAt)更改为其他名称.

class Post extends Model {}
Post.init({ /* 这是属性 */ }, {
  sequelize,
  paranoid: true,

  // 如果要为 deletedAt 列指定自定义名称
  deletedAt: 'destroyTime'
});

删除

当调用 destroy 方法时,将发生软删除:

await Post.destroy({
  where: {
    id: 1
  }
});
// UPDATE "posts" SET "deletedAt"=[timestamp] WHERE "deletedAt" IS NULL AND "id" = 1

如果想要硬删除,并且模型是 paranoid,则可以使用 force: true 参数强制执行:

await Post.destroy({
  where: {
    id: 1
  },
  force: true
});
// DELETE FROM "posts" WHERE "id" = 1

以静态的 destroy 方法为例(Post.destroy):

const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy(); // 只设置 `deletedAt` 标志
await post.destroy({ force: true }); // 真的会删除记录

恢复

要恢复软删除的记录,可以使用 restore 方法:

// 展示实例 `restore` 方法的示例
// 我们创建一个帖子,对其进行软删除,然后将其还原
const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy();
console.log('soft-deleted!');
await post.restore();
console.log('restored!');

// 展示静态 `restore` 方法的示例.
// 恢复每个 likes 大于 100 的软删除的帖子
await Post.restore({
  where: {
    likes: {
      [Op.gt]: 100
    }
  }
});

其他查询行为

Sequelize 执行的每个查询将自动忽略软删除的记录(原始查询除外),例如,findAll 方法将看不到软删除的记录,仅获取未删除的记录

即使调用提供了软删除记录主键的findByPk,结果也将是 null,如果想让查询看到被软删除的记录,可以将 paranoid: false 参数传递给查询方法

await Post.findByPk(123); // 如果 ID 123 的记录被软删除,则将返回 `null`
await Post.findByPk(123, { paranoid: false }); // 这将检索记录

await Post.findAll({
  where: { foo: 'bar' }
}); // 这将不会检索软删除的记录

await Post.findAll({
  where: { foo: 'bar' },
  paranoid: false
}); // 这还将检索软删除的记录