最近碰到一个动态查询条件的问题,比如,前端界面上可选择输入姓名、性别、年龄、电话等查询条件,后端根据是否输入来动态构建查询sql where条件(即如果未输入则不作为查询条件)。如果这些条件最终是全and或全or起来则相对容易处理,但如果既有and又有or则动态构建就困难了。
这个问题经抽象可表达为动态重写逻辑表达式,即先写出完整的表达式,然后排除无效部分。例如,对于下面的完整逻辑表达式字符串:
(a) or (b) and (c)
- 如果 a 无效则重写为 (b) and (c)
- 如果 b 无效则重写为 (a) or (c)
- 如果 c 无效则重写为 (a) or (b)
- 如果 a 和 b 都无效则重写为 (c)
- ...
- 如果全都无效则返回null
这个问题如何通用地解决呢?初看起来似乎很难,无从下手,但用ANTLR来解决则简单到出乎你的意料。
1、定义逻辑表达式语法
1 # LogicExpr.g4文件 2 3 grammar LogicExpr; 4 5 stat: expr ; 6 7 expr: expr AND expr # and 8 | expr OR expr # or 9 | '(' expr ')' # group 10 | VAR # var 11 ; 12 13 VAR : '(' KEY ')' ; 14 15 AND: 'and' ; 16 OR: 'or' ; 17 KEY: [a-zA-Z0-9_]+ ; 18 WS: [ \t\r\n]+ -> skip ;