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

QLExpress

戚研
2023-12-01

JAVA后端开发知识总结(持续更新…)


QLExpress



一、概述

  由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。 它是线程安全的,引擎运算过程中产生的临时变量都是ThreadLocal类型

二、语法

2.1 操作符

  • 操作符和运算符
  • 支持 +、-、*、/、<、>、<=、>=、==、!=、<>、%、mod、++等
  • in、like(sql语法)、&&、||、!
  • 支持for、break、continue、if then else 等标准的程序控制逻辑
  • 三元运算符
  • JAVA对象操作
  • 属于弱类型语言,不能定义类型声明,更不能用Templete(Map<String,List>等)。
  • 不支持Lambda表达式。

2.2 Operator扩展

  QLExpress主要通过子类实现Operator提供的executeInner() 来进行操作符定义,然后可以通过addFunction或addOperator注入到ExpressRunner中。

  • 方法1
ExpressRunner runner = new ExpressRunner();
// 关键字替换
runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("则", "then", null);
runner.addOperatorWithAlias("否则", "else", null);

// QL 表达式
String exp = "如果  (语文+数学+英语>270) 则 {return 1;} 否则 {return 0;}";
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.execute(exp,context,null,false,false,null);
  • 方法2——自定义Operator
  • runner.addOperator(“join”, new JoinOperator());:添加操作符号,可以设置优先级。
  • runner.replaceOperator("+", new JoinOperator());:替换操作符处理。
  • runner.addFunction(“join”, new JoinOperator());:通过自定义的Operator来实现函数。
//定义一个继承自 Operator 的操作符
public class JoinOperator extends Operator{
	public Object executeInner(Object[] list) throws Exception {
		Object opdata1 = list[0];
		Object opdata2 = list[1];
		if(opdata1 instanceof List){
			((List)opdata1).add(opdata2);
			return opdata1;
		}else{
			List result = new ArrayList();
			result.add(opdata1);
			result.add(opdata2);
			return result;				
		}
	}
}

// 使用
// addOperator()——返回结果:[1, 2, 3]
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
// 传入自定义的 Operator
runner.addOperator("join",new JoinOperator());
Object r = runner.execute("1 join 2 join 3", context, null, false, false);
System.out.println(r);

2.3 Function相关——绑定某个 Method

  • addFunctionOfClassMethod():绑定类方法
  • addFunctionOfServiceMethod():绑定对象方法
public class BeanExample {

	public static String upper(String abc) {
		return abc.toUpperCase();
	}
	
	public boolean anyContains(String str, String searchStr) {
        char[] s = str.toCharArray();
        for (char c : s) {
            if (searchStr.contains(c + "")) {
                return true;
            }
        }
        return false;
    }
}

ExpressRunner runner = new ExpressRunner();

runner.addFunctionOfClassMethod("取绝对值", Math.class.getName(), "abs", new String[] { "double" }, null);

runner.addFunctionOfClassMethod("转换为大写", BeanExample.class.getName(), "upper", new String[] { "String" }, null);

runner.addFunctionOfServiceMethod("打印", System.out, "println",new String[] { "String" }, null);

runner.addFunctionOfServiceMethod("contains", new BeanExample(), "anyContains", new Class[] { String.class, String.class }, null);
String exp = “取绝对值(-100);转换为大写(\"hello world\");打印(\"你好吗?\");contains("helloworld",\"aeiou\")”;

runner.execute(exp, context, null, false, false);

2.4 Macro 宏定义

  • addMacro():用一个变量替换一段文本
runner.addMacro("计算平均成绩", "(语文+数学+英语)/3.0");
runner.addMacro("是否优秀", "计算平均成绩>90");

IExpressContext<String, Object> context =new DefaultContext<String, Object>();
context.put("语文", 88);
context.put("数学", 99);
context.put("英语", 95);

Object result = runner.execute("是否优秀", context, null, false, false);
System.out.println(r);

三、API

  • execute()
// 执行一段文本
Object execute(String expressString,                     // 程序文本
				IExpressContext<String,Object> context,  // 执行上下文,可以扩展为包含 ApplicationContext
				List<String> errorList,                 // 输出的错误信息 List
				boolean isCache,                        // 是否使用 Cache 中的指令集,建议为 true
				boolean isTrace,                        // 是否输出详细的执行指令信息,建议为 false
				Log aLog.                               // 输出的 log
);
  • 快速使用
ExpressRunner runner = new ExpressRunner();

DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.put("a",1);
context.put("b",2);
context.put("c",3);

String express = "a+b*c";

Object r = runner.execute(express, context, null, true, false);
System.out.println(r);

参考文档

QLExpress基本语法

 类似资料:

相关阅读

相关文章

相关问答