You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在jOOQ中实现自动过滤逻辑删除数据的功能?

在jOOQ中实现自动过滤逻辑删除行的方案

针对你提出的自动扩展SQL过滤逻辑删除行的需求,在jOOQ里有几种更优的实现方式,无需破坏标准语法或进行大量类包装:

1. 基于ExecuteListener拦截查询(推荐)

这是目前最成熟的生产级方案,完全不侵入业务代码的标准jOOQ语法:

  • 实现ExecuteListener接口,在renderStart阶段获取当前Query对象
  • 遍历查询的FROM和JOIN节点,提取所有涉及的表
  • 结合自有元数据判断表是否支持逻辑删除
  • 处理JOIN条件:遍历每个Join对象,若其ON条件未包含deleted判断,则用and()拼接deleted = 0条件
  • 处理主表WHERE条件:检查查询的WHERE子句,若主表未指定deleted条件,则添加对应的过滤规则

示例代码片段:

@Override
public void renderStart(ExecuteContext ctx) {
    Query query = ctx.query();
    if (query instanceof SelectQuery<?>) {
        SelectQuery<?> select = (SelectQuery<?>) query;
        
        // 处理所有JOIN的逻辑删除条件
        for (Join<?> join : select.getJoins()) {
            Table<?> table = join.getTable();
            if (isSoftDeleteSupported(table)) {
                Condition onCondition = join.getCondition();
                Condition deletedCondition = table.field("deleted").eq(0);
                if (onCondition == null) {
                    join.setCondition(deletedCondition);
                } else if (!containsDeletedCondition(onCondition)) {
                    join.setCondition(onCondition.and(deletedCondition));
                }
            }
        }
        
        // 处理主表的逻辑删除条件
        if (!select.getFrom().isEmpty()) {
            Table<?> mainTable = select.getFrom().get(0);
            if (isSoftDeleteSupported(mainTable)) {
                Condition where = select.getWhere();
                Condition deletedCondition = mainTable.field("deleted").eq(0);
                if (where == null) {
                    select.addConditions(deletedCondition);
                } else if (!containsDeletedCondition(where)) {
                    select.addConditions(deletedCondition);
                }
            }
        }
    }
}

// 自定义方法:判断表是否支持逻辑删除
private boolean isSoftDeleteSupported(Table<?> table) {
    // 结合自有元数据实现判断逻辑
    return true;
}

// 自定义方法:检查条件中是否已包含deleted过滤
private boolean containsDeletedCondition(Condition condition) {
    // 遍历条件表达式,判断是否存在deleted相关条件
    return false;
}

2. 代码生成器扩展

通过jOOQ代码生成器,为支持逻辑删除的表自动生成带过滤条件的方法或别名:

  • 扩展代码生成器的模板,为目标表生成notDeleted()方法,返回已附加deleted = 0条件的Table实例
  • 业务代码中只需调用table.notDeleted()替代直接使用表对象,即可自动带上逻辑删除过滤
  • 这种方式完全贴合jOOQ原生语法,开发体验接近标准API

3. 自定义DSLContext包装器

创建自定义的DSLContext包装类,重写生成查询的核心方法:

  • 在生成SelectQuery的过程中,自动注入逻辑删除过滤条件
  • 业务代码只需替换默认的DSLContext实例,无需修改原有查询写法

关于QOM的说明

QOM目前仍处于实验性阶段,暂不支持完整的JOIN节点遍历。jOOQ官方正在逐步完善其功能,预计后续稳定版本会脱离实验状态,但现阶段不建议在生产环境依赖QOM实现核心逻辑。

对比现有方案的优势

  • 避免了自定义顶层方法破坏标准SQL语法的问题,完全兼容jOOQ原生API
  • 无需进行大量类包装,降低了版本变更带来的维护成本

内容的提问来源于stack exchange,提问作者db2222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:10:33