sequelize-cli 软删除 与多选删除、恢复 及多选批量恢复

一、软删除

1、逻辑

我们先说一下删除到回收站的原理,其实就是在数据库增加了一个字段。如果这个字段没有值,就表示这是一个正常的数据。如果这个字段有值了,就表示它被删除到回收站了。数据本身其实一直都存在,只是多了个字段表示是否在回收站中而已。

这种需求在Sequelize中,能非常轻松的实现,标准的术语叫做:软删除。详情可以看官方文档的这一章:传送门

2、实例

现在,我们以文章表为例,来实现软删除。做之前,需要先在文章表中,增加一个字段,名叫做:deletedAt,看名字就知道了,这是用来表示什么时候删除的。如果这字段有值,那就表示被删到回收站中了。

2.1、 新建迁移,增加 deletedAt 字段
sequelize migration:create --name add-deleted-at-to-article

修改迁移里的内容

async up(queryInterface, Sequelize) {
  await queryInterface.addColumn('Articles', 'deletedAt', {
    type: Sequelize.DATE
  });

  await queryInterface.addIndex(
    'Articles', {
      fields: ['deletedAt']
    });
},

async down(queryInterface, Sequelize) {
  await queryInterface.removeColumn('Articles', 'deletedAt');
}

  • 增加了deletedAt字段,使用的是日期类型。
  • 给这个字段增加了索引,因为我们需要经常使用这个字段,用来查询正常的数据,和在回收站中数据。
2.2、运行一下迁移
sequelize db:migrate
2.3、修改模型
Article.init({
   // ...
  deletedAt: {
      type: DataTypes.DATE
    }
}, {
  sequelize,
  paranoid: true,
  modelName: 'Article',
});

  • 模型的定义里,增加deletedAt
  • 底下,增加paranoid: true
2.4、测试软删除

在这里插入图片描述

接着再调用查询文章列表的接口,发现列表里,根本就没有id: 101的文章

观察下 SQL,发现指定了,只查deletedAt字段为空 (Null)的数据。而我们这条数据的deletedAt字段里有值,当然就查不到了。
在这里插入图片描述

3、查询已删除的数据

现在文章已经被删掉了,在回收站功能模块里,如何才能查询到已被删除的文章呢?方法也很简单,只需要在查询的条件里添加一个paranoid: false即可。

const condition = {
}

// 查询被软删除的数据
if (query.deleted === 'true') {
  condition.paranoid = false;
  condition.where.deletedAt = {
    [Op.not]: null
  }
}

if (query.title) {
}

  • condition的下面,先判断一下,如果用户传递了deleted=true参数,那就表明当前要显示的是回收站中的数据。
  • 加上paranoid = false,这样查询到的数据,除了正常数据外,还会包含被软删除的数据。
  • 但我们这里要实现只查询被软删除的数据,正常数据不要。所以在where里,还要排除掉deletedAt不为null的数据。这样查到的数据,就只有被软删除的了。

二、多选批量删除

刚才我们实现了单条文章记录软删除。如果要删除多篇记录,应该怎么办呢?方法也很简单,让前端传递过来一个数组就行了,里面包含所有要删除的文章 ID

删除与多选批量删除,其实没有必要写两个接口,就公用一个最好了。我们将之前写的删除文章接口,直接删掉,改为:

/**
 * 删除到回收站
 * POST /admin/articles/delete
 */
router.post('/delete', async function (req, res) {
  try {
    const { id } = req.body;

    await Article.destroy({ where: { id: id } });
    success(res, '已删除到回收站。');
  } catch (error) {
    failure(res, error);
  }
});

  • 需要注意的是,因为要传递数组过来,这里用DELETE请求就不合适了。Express默认不会解析DELETE请求中的body,所以我们改为POST请求。
  • 接受到用户传递的所有文章 ID 后,直接丢到where里,调用destroy方法删掉即可。
  • 这里的 ID,可以是单条记录值,也可以是数组

三、彻底删除

回收站里的数据,如果确实不想要了,要彻底删除掉,又该怎么做的呢?Sequelize也给我们安排好了,删除的时候,传递force: true就能实现了。

我们现在完成彻底删除文章接口,当然也同时支持彻底删除单条和多条记录。

/**
 * 彻底删除
 * POST /admin/articles/force_delete
 */
router.post('/force_delete', async function (req, res,) {
  try {
    const { id } = req.body;

    await Article.destroy({
      where: { id: id },
      force: true
    });
    success(res, '已彻底删除。');
  } catch (error) {
    failure(res, error);
  }
});

四、恢复/批量恢复

既然能删除到回收站,那对应的就得有恢复功能恢复功能,同样的可以恢复单条记录,也能批量恢复多条记录

Seqelize已经帮我们准备好了恢复方法,就是 restore方法,下面来看代码。

/**
 * 从回收站恢复
 * POST /admin/articles/restore
 */
router.post('/restore', async function (req, res) {
  try {
    const { id } = req.body;

    await Article.restore({ where: { id: id } });
    success(res, '已恢复成功。')
  } catch (error) {
    failure(res, error);
  }
});

总结

  • Sequelize里,实现软删除是非常容易的事情。
  • 数据库中要增加deletedAt字段,来记录当前文章是否被删除。
  • 模型里,要添加paranoid: true
  • 现在再删除文章,就会变成软删除了。
  • 原理就是在deletedAt字段添加了个时间而已。
  • 在查的时候,我们只查deletedAt字段为空的记录。用户就以为数据被删掉了,其实并没有。
  • 要查询被软删除的记录,需要添加paranoid: false
  • 从回收站恢复数据,可以用restore方法。
  • 要彻底删掉记录,可以在删除时,传递force: true参数。
  • 还有一个值得思考的地方是,很多项目都有删除用户的功能。但是用户往往关联了大量的数据,特别是涉及到了支付相关的项目。如果真的把用户删掉了,那么将来追踪订单都会变的困难。这种情况下,考虑使用软删除,也是一种解决办法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值