需求:将sql表达式的where条件转换为FilterList,简化开发代码量。
例:( 3014 > 10 or 2205 > 100 ) and 3001 = 1
转换结果为:
FilterList AND (2/2): [SingleColumnValueFilter (can, 3001, EQUAL, 1), FilterList OR (2/2): [SingleColumnValueFilter (can, 3014, GREATER, 10), SingleColumnValueFilter (can, 2205, GREATER, 100)]]
代码如下:
注:由于查询过程中可能或有and或者or英文存在,则使用 &&替换and,|| 替换or,进行查询
package toolkit.hbase.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import java.util.*;
/**
* hbase sql转换为查询条件FilterList
*
* @author WeiJinglun
* @date 2019/10/18
*/
public class Tool {
private static final String AND = "&&";
private static final String OR = "||";
private static final char YU = '&';
private static final char HUO = '|';
/**
* 提取where条件中的列
*
* @param s
* @return
*/
public static Set<String> transformColumnList(String s) {
Set<String> columnSet = new HashSet<>();
//去除收尾括号和空格
s = s.trim();
if (s.charAt(0) == '(' && s.charAt(s.length() - 1) == ')') {
s = s.substring(1, s.length() - 1);
}
//不包含&&或||,判定为最简单表达式,之间转换
if (!s.contains(OR) && !s.contains(AND)) {
columnSet = transformSimpleColumnList(s);
} else {
int j = 0;//括号数量
boolean type = true;//true为and;false为or
for (int i = 0; i < s.length(); i++) {
//先判断是否为左括号
if (s.charAt(i) == '(') {
++j;//将括号对数+1
} else if (s.charAt(i) == ')') {
--j;//将括号对数-1
}
//检测前面是否还有括号
if (j == 0) {
if (s.charAt(i) == YU && s.charAt(i + 1) == YU) {
//说明最外层的是and
break;
} else if (s.charAt(i) == HUO && s.charAt(i + 1) == HUO) {
//说明最外层的是or
type = false;
break;
}
}
}
int start = 0;
for (int i = 0; i < s.length() - 2; i++) {
//找匹配的右括号
//先判断是否为左括号
if (s.charAt(i) == '(') {
++j;//将括号对数+1
} else if (s.charAt