
本文介绍如何通过自定义 visitoradapter 类,在 jsqlparser 中实现“未显式支持即报错”的严格解析策略,避免默认忽略 insert、group by 等未处理语句导致的静默失败。
本文介绍如何通过自定义 visitoradapter 类,在 jsqlparser 中实现“未显式支持即报错”的严格解析策略,避免默认忽略 insert、group by 等未处理语句导致的静默失败。
JSqlParser 默认提供的 *VisitorAdapter(如 ExpressionVisitorAdapter、StatementVisitorAdapter)采用“空实现”策略:所有 visit 方法体为空,未覆盖的方法调用时无任何反馈,导致不支持的语法(如 INSERT、GROUP BY、HAVING、子查询、窗口函数等)被静默跳过——这对构建轻量级专用数据库极其危险,可能掩盖语义误判或执行逻辑漏洞。
要实现“仅允许白名单语法”的严格校验,推荐方案是编写自定义的严格适配器类(StrictVisitorAdapter),将所有 visit 方法默认实现为抛出 UnsupportedOperationException,再仅对明确支持的节点类型进行选择性重写。例如:
public class StrictStatementVisitor extends StatementVisitorAdapter {
@Override
public void visit(Select select) {
select.getSelectBody().accept(new StrictSelectBodyVisitor());
}
// 其他未支持语句一律拒绝
@Override
public void visit(Insert insert) {
throw new UnsupportedOperationException("INSERT statements are not supported");
}
@Override
public void visit(Update update) {
throw new UnsupportedOperationException("UPDATE statements are not supported");
}
@Override
public void visit(Delete delete) {
throw new UnsupportedOperationException("DELETE statements are not supported");
}
}
class StrictSelectBodyVisitor extends SelectBodyVisitorAdapter {
@Override
public void visit(PlainSelect plainSelect) {
if (plainSelect.getGroupBy() != null) {
throw new UnsupportedOperationException("GROUP BY is not supported");
}
if (plainSelect.getHaving() != null) {
throw new UnsupportedOperationException("HAVING clause is not supported");
}
// 仅允许基础列、常量、二元比较(如 =, >)
plainSelect.getSelectItems().forEach(item -> item.accept(new StrictSelectItemVisitor()));
plainSelect.getWhere().ifPresent(w -> w.accept(new StrictExpressionVisitor()));
}
}关键实践要点:
- ✅ *继承 `VisitorAdapter` 而非直接实现接口**:复用已有方法签名,避免遗漏;
- ✅ 在构造解析器后显式设置 visitor:parser.parse(...).accept(new StrictStatementVisitor());
- ⚠️ 注意递归访问:子节点(如 Where, OrderBy, Expression)需各自使用对应严格 visitor,否则校验链断裂;
- ? 可配合 CCJSqlParserManager 的 parseStatements() 批量校验多语句,统一拦截非法 DDL/DML;
- ? 进阶可封装为 StrictSqlValidator 工具类,结合配置化白名单(如支持 LIMIT 但禁用 OFFSET),提升可维护性。
该方式无需修改 JSqlParser 源码,完全符合开闭原则,是构建领域限定型 SQL 引擎最简洁、健壮的集成方案。


















