baomidou/mybatis-plus · error · MybatisPlusException
非法SQL,where条件中不能使用【or】关键字,错误or信息:{}
Error message
非法SQL,where条件中不能使用【or】关键字,错误or信息:{} What it means
IllegalSQLInnerInterceptor (jsqlparser 4.9) throws when the parsed WHERE condition's top-level expression (after unwrapping parentheses) is an OrExpression. The interceptor is a policy check that forbids OR in WHERE clauses (usually to prevent index-bypassing scans); the offending OR expression is appended to the message.
Source
Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-4.9/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java:176
List<Join> joins = delete.getJoins();
validWhere(where, table, (Connection) obj);
validJoins(joins, table, (Connection) obj);
}
/**
* 验证expression对象是不是 or、not等等
*
* @param expression ignore
*/
private void validExpression(Expression expression) {
while (expression instanceof Parenthesis) {
Parenthesis parenthesis = (Parenthesis) expression;
expression = parenthesis.getExpression();
}
//where条件使用了 or 关键字
if (expression instanceof OrExpression) {
OrExpression orExpression = (OrExpression) expression;
throw new MybatisPlusException("非法SQL,where条件中不能使用【or】关键字,错误or信息:" + orExpression.toString());
} else if (expression instanceof NotEqualsTo) {
NotEqualsTo notEqualsTo = (NotEqualsTo) expression;
throw new MybatisPlusException("非法SQL,where条件中不能使用【!=】关键字,错误!=信息:" + notEqualsTo.toString());
} else if (expression instanceof BinaryExpression) {
BinaryExpression binaryExpression = (BinaryExpression) expression;
// TODO 升级 jsqlparser 后待实现
// if (binaryExpression.isNot()) {
// throw new MybatisPlusException("非法SQL,where条件中不能使用【not】关键字,错误not信息:" + binaryExpression.toString());
// }
if (binaryExpression.getLeftExpression() instanceof Function) {
Function function = (Function) binaryExpression.getLeftExpression();
throw new MybatisPlusException("非法SQL,where条件中不能使用数据库函数,错误函数信息:" + function.toString());
}
if (binaryExpression.getRightExpression() instanceof Subtraction) {
Subtraction subSelect = (Subtraction) binaryExpression.getRightExpression();
throw new MybatisPlusException("非法SQL,where条件中不能使用子查询,错误子查询SQL信息:" + subSelect.toString());
}
} else if (expression instanceof InExpression) {View on GitHub (pinned to bf67d90747)
Solutions
- Rewrite the predicate without top-level OR: use IN (...), BETWEEN, or split the comparison so the first indexed column stands alone.
- If OR is legitimately needed, remove IllegalSQLInnerInterceptor from the interceptor chain for that statement or entirely, or scope it via InterceptorIgnoreHelper (@InterceptorIgnore(illegalSql = "true")).
- Review with the DBA whether the OR's columns are indexed; if both sides are indexed the policy may be relaxed deliberately.
Example fix
// before SELECT * FROM user WHERE name = ? OR id = ?; // after SELECT * FROM user WHERE id = ? OR-deleted -- use indexed equality first / IN list SELECT * FROM user WHERE id IN (?) AND name = ?;
Defensive patterns
Strategy: validation
Validate before calling
// Static guard in code review / unit test: scan mapped SQL for top-level OR // e.g. with a test that parses XML/annotations and asserts no OrExpression at WHERE top level, // or simply forbid QueryWrapper.or() usage via ArchUnit: // noClasses().should().callMethod(QueryWrapper.class, "or")
Try / catch
try {
mapper.selectList(wrapper);
} catch (MybatisPlusException e) {
if (String.valueOf(e.getMessage()).contains("不能使用【or】")) {
log.error("policy violation: rewrite predicate without OR: {}", e.getMessage());
}
} Prevention
- Codify the no-OR policy in review checklists and forbid wrapper.or() via static analysis.
- Provide approved rewrites (IN, range predicates) in team docs.
- Use @InterceptorIgnore(illegalSql="true") deliberately and track each usage.
When it happens
Trigger: Executing a mapped statement or wrapper query whose WHERE contains a top-level OR (e.g. name = ? OR age = ?) while the IllegalSQLInnerInterceptor is registered in MybatisPlusInterceptor.
Common situations: Team policy bans OR for performance; a developer adds queryWrapper.or(...) or writes native SQL with OR, and the interceptor rejects it at execution time. Parenthesized ORs are unwrapped, so wrapping in parens does not bypass it.
Related errors
- 非法SQL,where条件中不能使用【!=】关键字,错误!=信息:{}
- 非法SQL,where条件中不能使用数据库函数,错误函数信息:{}
- 非法SQL,where条件中不能使用子查询,错误子查询SQL信息:{}
- 非法SQL,SQL未使用到索引, table:{}, columnName:{}
- 非法SQL,where条件中不能使用【or】关键字,错误or信息:{}
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/d22373015d0df6b2.
Report an issue: GitHub.