QLExpress的各种使用场景, 可参考:https://toscode.gitee.com/cuibo119/QLExpress
表达式中使用对象
@Test
public void testABC() throws Exception {
String express = "object.amount * 2 + object.volume";
ExpressRunner runner = new ExpressRunner(false, true);
DefaultContext<String, Object> context = new DefaultContext<>();
ObjectBean tempObject = new ObjectBean(100, 60);
context.put("object", tempObject);
Object result = runner.execute(express, context, null, false, true);
System.out.println(result);
Assert.assertNotSame("数据执行错误", 200, result);
}
最后的语法树:
1: STAT_BLOCK:STAT_BLOCK STAT_BLOCK
2: STAT_SEMICOLON:STAT_SEMICOLON STAT_SEMICOLON
3: +:+ +
4: *:* *
5: .:FIELD_CALL FIELD_CALL
6: object:ID ID
6: amount:CONST_STRING CONST
5: 2:CONST_INTEGER CONST
4: .:FIELD_CALL FIELD_CALL
5: object:ID ID
5: volume:CONST_STRING CONST
1:LoadAttr:object
2:OP : FieldCall:amount OPNUMBER[1]
3:LoadData 2
4:OP : * OPNUMBER[2]
5:LoadAttr:object
6:OP : FieldCall:volume OPNUMBER[1]
7:OP : + OPNUMBER[2]
260
自定义运算符
/**
* 定义连加的操作符
*/
public class AddNOperator extends Operator {
@Override
public Object executeInner(Object[] list) {
int r = 0;
for (Object item : list) {
r = r + (Integer)item;
}
return r;
}
}
使用
@Test
public void testAddNByFunction() throws Exception {
//定义表达式,相当于1+2+3+4
String exp = "addN(1,2,3,4)";
ExpressRunner runner = new ExpressRunner();
//定义方法addN,其实现为AddNOperator
runner.addFunction("addN", new AddNOperator());
int r = (Integer)runner.execute(exp, null, null, false, false);
System.out.println(r);
Assert.assertEquals("操作符执行错误", 10, r);
}
脚本中自定义函数
@Test
public void testFunc() throws Exception {
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.put("a", 3);
context.put("b", 1);
String express = "function add(int a,int b){" +
"return a+b;" +
"};" +
"return add(a,b);";
Object funcResult = runner.execute(express, context, null, false, false);
System.out.println("add(a,b)=" + funcResult);
}
扩展操作符:替换if,then,else等关键字
@Test
public void testReplaceIfThenElse() throws Exception {
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("则", "then", null);
runner.addOperatorWithAlias("否则", "else", null);
context.put("语文", 100);
context.put("数学", 100);
context.put("英语", 100);
String express = "如果 ((语文+数学+英语)>270) 则 return 1;否则 return 0;";
Object result = runner.execute(express, context, null, true, false);
System.out.println(result);
}
使用类方法
public class AvgClass {
public AvgClass() {
}
public double avg(double a, double b){
return 0.5 * (a + b);
}
}
@Test
public void testMethod() throws Exception {
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.put("a", 2.5);
context.put("b", 3.5);
runner.addFunctionOfClassMethod("取平均值", AvgClass.class.getName(), "avg",
new String[]{
"double", "double"}, null);
String exp = "return 取平均值(a, b);";
Object result = runner.execute(exp, context, null, false, false);
System.out.println(result); // 3.0
}