JEXL3中如何重写赋值运算符=并实现类SQL的IN运算符功能
JEXL3 类SQL语法扩展核心改造类清单
重写=运算符为相等判断(兼容WHERE A=B写法)
无需修改官方语法模板重新生成解析器,仅需重写2个核心类即可实现:
org.apache.commons.jexl3.Interpreter:作为AST节点遍历执行的核心入口,重写其visit(ASTAssignment node, Object data)方法,废弃原有的变量赋值逻辑:先分别计算赋值节点的左右子节点得到实际运算值,再调用算术组件的相等判断方法返回布尔结果即可。若需要同时保留赋值能力(例如SET子句中
=为赋值语义、WHERE子句中=为相等判断),可在visit方法中增加上下文标记判断,按场景分支执行不同逻辑。org.apache.commons.jexl3.JexlArithmetic(可选改造):如果需要适配SQL风格的弱类型相等规则(比如数字字符串与数值自动转型比较、NULL值安全判断),可重写其equals(Object left, Object right)方法,自定义匹配逻辑即可。
新增IN运算符(兼容WHERE col IN (v1,v2,...)写法)
该需求需要同时覆盖解析层与执行层,核心改造类如下:
- 解析层改造:
- 推荐方案:基于官方源码的
Parser.jjt语法模板新增IN运算符规则,将IN定义为优先级与相等判断一致的比较运算符,匹配到左值 IN (值列表)结构时生成自定义AST节点(例如命名为ASTInOperator),再通过JJTree编译生成对应的解析器类与AST节点类。 - 轻量方案:继承
org.apache.commons.jexl3.parser.StringParser,在词法解析阶段做预处理,将IN (结构替换为自定义函数调用格式,该方案无需编译语法模板,但复杂嵌套场景兼容性较差。
- 推荐方案:基于官方源码的
- 执行层改造:
- 扩展自定义
Interpreter实现类,新增ASTInOperator节点的visit逻辑:取出左节点的目标值,将右节点括号内的列表解析为集合/数组结构,判断目标值是否存在于集合中返回布尔结果。 - 扩展
JexlArithmetic类,新增in(Object target, Object collection)方法,封装IN运算核心逻辑:兼容右值为数组、List、Set等多种集合类型,支持弱类型匹配、NULL值处理等SQL语义,供Interpreter直接调用。
- 扩展自定义
所有自定义实现完成后,通过JexlBuilder注入自定义的Interpreter、Arithmetic、Parser组件,构建JexlEngine实例即可生效。
内容的提问来源于stack exchange,提问作者100rabh
相关产品推荐
相关产品推荐

