当前位置: 首页 > 工具软件 > QLExpress > 使用案例 >

QLExpress-阿里规则引擎

祁坚壁
2023-12-01

QLExpress:GitHub - alibaba/QLExpress: QLExpress is a powerful, lightweight, dynamic language for the Java platform aimed at improving developers’ productivity in different business scenes.

public static void main(String[] args) {
    // 统计时,会传递日期和数据板块id,数据板块id的用处就是获取计算公式
    // 假如这就是我们获取到的某一个数据板块的公式
    String str = "avg(item_code_f,item_code_b) +item_code_a ÷ item_code_k - 100";
    // 处理一下÷和×,毕竟是以*和/作为乘法除法符号的
    str = str.replace("÷","/");
    str = str.replace("×","*");
    // 定义一个正则表达式,过滤掉计算符号
    String regex = "[()*+/-]";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(str);
    List<String> list = new ArrayList<>();
    // 这里注意要先转成Set然后再转成List,因为有可能计算的时候要使用一个数据项的值多次,但是其实都是同一个值
    list.addAll(Arrays.asList(m.replaceAll(" ").split(" ")).stream().filter(s->{
       // 通过流来单独过滤avg和数字
       return !s.equals("avg")&&!s.equals("")&&!isNumeric(s);
    }).collect(Collectors.toSet()));
    // 输出一下结果:[item_code_f,item_code_b,item_code_a,item_code_k],这样就成功的将数据项编码给分离出来
    System.out.println(list.toString());
    // 然后通过数据项编码可以把对应的统计日期下,对应的数据项编码的数量或者金额获取到,然后通过replace()方法替换调即可
    // 具体从数据库里取值和替换的代码省略。。。嘿嘿,偷个懒 >_<||| 
    // 最后得到大概这样的数据:avg(1000,2000)+30/2-100
    String express = "avg(1000,2000)+30/2-100";
    // 接下来就是使用QLExpress了
    ExpressRunner runner = new ExpressRunner();
    // 先定义我们需要的avg函数
    runner.addFunction("avg",new Operator(){
        @Override
        public Object executeInner(Object[] objArray) throw Exception{
            Double total=0.0;
            Double average=0.0;
            for(Double obj: objArray){
                Double num=Double.valueOf(obj.toString());
                total = total + num;
            }
            average = total/objArray.length;
            return average;
        }
    });
    // 计算结果,这里是一个重载方法,没有log
  	Object result = runner.execute(express,null, null, false,false);
    // 顺利拿到结果:1415
    Double resultNum = Double.valueOf(result.toString());
}

/**
 * 判断是否是数字
 */
public static boolean isNumeric(String str){
    Pattern pattern = Pattern.compile("[0-9]*");
    Matcher isNum = pattern.matcher(str);
    if( !isNum.matches() ){
        return false;
    }
    return true;
}

 使用QLExpress动态制定计算公式_佛祖保佑永不宕机的博客-CSDN博客_qlexpress表达式

 类似资料: