如何为Objection特定模型的所有查询添加默认where子句?
Objection 框架软删除默认过滤实现方案
有两种成熟的实现方式,不需要每次手动加where deleted_at is null条件:
方案1:使用Objection官方软删除插件(推荐)
这是最省心的方案,插件已经封装了所有常用的软删除逻辑:
const { Model } = require('objection'); const softDelete = require('@objection/soft-delete'); // 定义软删除基础模型 const SoftDeleteBase = softDelete({ columnName: 'deleted_at', // 匹配你的软删除字段 deletedValue: new Date(), // 删除时写入的时间戳 notDeletedValue: null, // 未删除的字段值 })(Model); // 所有需要软删除的业务模型继承该基础模型即可 class Post extends SoftDeleteBase { static tableName = 'posts'; }
生效后所有常规查询会自动追加where deleted_at is null条件,额外的操作方法:
- 需要查询包含已删除的记录:调用
.withDeleted() - 需要永久删除记录:调用
.hardDelete() - 需要恢复已删除的记录:调用
.undelete()
方案2:自定义模型钩子(无额外依赖)
如果不想引入第三方插件,可以自行重写模型的查询前置钩子实现:
const { Model } = require('objection'); class SoftDeleteBase extends Model { static beforeFind(queryContext) { super.beforeFind(queryContext); // 未指定查询已删除记录时自动追加过滤条件 if (!queryContext.includeDeleted) { queryContext.query.whereNull(`${this.tableName}.deleted_at`); } } }
需要查询包含已删除记录时,手动传入上下文参数即可:
Post.query().context({ includeDeleted: true })
Knex 层面的补充方案
如果需要全局给所有Knex查询加软删除过滤,可以扩展Knex查询构建器:
knex.QueryBuilder.prototype.withNotDeleted = function(table) { return this.whereNull(`${table}.deleted_at`); }
该方案粒度较粗,不如模型层实现灵活,仅适合全库所有表都用统一软删除规则的场景。
内容的提问来源于stack exchange,提问作者Eugene Kim
相关产品推荐
相关产品推荐

