最近碰到一个动态查询条件的问题,比如,前端界面上可选择输入姓名、性别、年龄、电话等查询条件,后端根据是否输入来动态构建查询sql where条件(即如果未输入则不作为查询条件)。如果这些条件最终是全and或全or起来则相对容易处理,但如果既有and又有or则动态构建就困难了。

这个问题经抽象可表达为动态重写逻辑表达式,即先写出完整的表达式,然后排除无效部分。例如,对于下面的完整逻辑表达式字符串:

(a) or (b) and (c)
  1. 如果 a 无效则重写为 (b) and (c) 
  2. 如果 b 无效则重写为 (a) or (c) 
  3. 如果 c 无效则重写为 (a) or (b)
  4. 如果 a 和 b 都无效则重写为 (c)  
  5. ...
  6. 如果全都无效则返回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 ;
View Code

相关文章: