阿里规则引擎 QLExpress 学习

发布时间 2023-11-07 16:56:48作者: Kllin

maven依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>QLExpress</artifactId>
    <version>3.2.0</version>
</dependency>

简单运算表达式

ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<>();
context.put("a",1);
context.put("b",2);
context.put("c",3);
String express = "a + b * c";
Object execute = runner.execute(express, context, null, true, false);
System.out.println(execute);

逻辑表达式

ExpressRunner runner = new ExpressRunner();
runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("则", "then", null);
runner.addOperatorWithAlias("否则", "else", null);

DefaultContext<String, Object> context = new DefaultContext<>();
context.put("语文", 100);
context.put("数学", 100);
context.put("英语", 90);
String express = "如果 (语文 + 数学 + 英语 > 270) 则 {return 1;} 否则 {return 0;";
Object execute = runner.execute(express, context, null, true, false);
System.out.println(execute);

复杂逻辑表达式

ExpressRunner runner = new ExpressRunner();
runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("或", "||", null);
runner.addOperatorWithAlias("且", "&&", null);
runner.addOperatorWithAlias("等于", "==", null);
runner.addOperatorWithAlias("大于", ">", null);
runner.addOperatorWithAlias("小于", "<", null);
runner.addOperatorWithAlias("则", "then", null);
runner.addOperatorWithAlias("否则", "else", null);
runner.addOperatorWithAlias("返回", "return", null);
runner.addFunctionOfClassMethod("获取JSON中的值", Test.class.getName(), "getValue", new String[]{"String"}, null);
runner.addFunctionOfClassMethod("字符串等于", Test.class.getName(), "equals", new String[]{"String", "String"}, null);

DefaultContext<String, Object> context = new DefaultContext<>();
String express = "如果 (获取JSON中的值(\"code\") 等于 1) 则 {返回 true} 否则 {返回 false}";
Object execute = runner.execute(express, new DefaultContext<>(), null, true, false);
System.out.println(execute);

// DefaultContext<String, Object> context = new DefaultContext<>();
// String express = "如果 ( 字符串等于( 获取JSON中的值(\"message\"), \"success\") ) 则 {返回 true} 否则 {返回 false}";
// Object execute = runner.execute(express, context, null, true, false);
// System.out.println(execute);

完整代码


import com.alibaba.fastjson.JSONObject;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ruoyi.common.core.utils.StringUtils;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class Test {
    public static void main(String[] args) throws Exception {

        // 简单运算表达式
//        ExpressRunner runner = new ExpressRunner();
//        DefaultContext<String, Object> context = new DefaultContext<>();
//        context.put("a",1);
//        context.put("b",2);
//        context.put("c",3);
//        String express = "a + b * c";
//        Object execute = runner.execute(express, context, null, true, false);
//        System.out.println(execute);


//        逻辑表达式
//        ExpressRunner runner = new ExpressRunner();
//        runner.addOperatorWithAlias("如果", "if", null);
//        runner.addOperatorWithAlias("则", "then", null);
//        runner.addOperatorWithAlias("否则", "else", null);
//
//        DefaultContext<String, Object> context = new DefaultContext<>();
//        context.put("语文", 100);
//        context.put("数学", 100);
//        context.put("英语", 90);
//        String express = "如果 (语文 + 数学 + 英语 > 270) 则 {return 1;} 否则 {return 0;}";
//        Object execute = runner.execute(express, context, null, true, false);
//        System.out.println(execute);

        //复杂逻辑表达式
        ExpressRunner runner = new ExpressRunner();
        runner.addOperatorWithAlias("如果", "if", null);
        runner.addOperatorWithAlias("或", "||", null);
        runner.addOperatorWithAlias("且", "&&", null);
        runner.addOperatorWithAlias("等于", "==", null);
        runner.addOperatorWithAlias("大于", ">", null);
        runner.addOperatorWithAlias("小于", "<", null);
        runner.addOperatorWithAlias("则", "then", null);
        runner.addOperatorWithAlias("否则", "else", null);
        runner.addOperatorWithAlias("返回", "return", null);
        runner.addFunctionOfClassMethod("获取JSON中的值", Test.class.getName(), "getValue", new String[]{"String"}, null);
        runner.addFunctionOfClassMethod("字符串等于", Test.class.getName(), "equals", new String[]{"String", "String"}, null);

//        DefaultContext<String, Object> context = new DefaultContext<>();
//        String express = "如果 (获取JSON中的值(\"code\") 等于 1) 则 {返回 true} 否则 {返回 false}";
//        Object execute = runner.execute(express, new DefaultContext<>(), null, true, false);
//        System.out.println(execute);

        DefaultContext<String, Object> context = new DefaultContext<>();
        String express = "如果 ( 字符串等于( 获取JSON中的值(\"message\"), \"success\") ) 则 {返回 true} 否则 {返回 false}";
        Object execute = runner.execute(express, context, null, true, false);
        System.out.println(execute);
    }

    /**
     * 获取JSON中属性的值
     *
     * @param name 属性名
     * @return 结果
     */
    public static Object getValue(String name) {
        String json = "{\"code\": 1,\"message\": \"success\"}";
        return JSONObject.parseObject(json).get(name);
    }

    /**
     * 判断两个值是否相等
     *
     * @param param1 值1
     * @param param2 值2
     * @return 结果
     */
    public static boolean equals(String param1, String param2) {
        return StringUtils.equals(param1, param2);
    }

}

仿实际应用场景

伪代码

if(新用户) {
  赠送优惠券;
} else {
  赠送积分;
}
if(有手机号){
  发送短信;
}

完整代码

import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class Test {

    public static void main(String[] args) throws Exception {
        ExpressRunner runner = new ExpressRunner();

        // 定义逻辑
        runner.addOperatorWithAlias("如果", "if", null);
        runner.addOperatorWithAlias("则", "then", null);
        runner.addOperatorWithAlias("否则", "else", null);

        // 定义执行方法
        runner.addFunctionOfClassMethod("赠送优惠券", Test.class.getName(), "sendCoupon", new Class[]{Integer.class}, null);
        runner.addFunctionOfClassMethod("赠送积分", Test.class.getName(), "sendIntegral", new Class[]{Integer.class}, null);
        runner.addFunctionOfClassMethod("发送短信", Test.class.getName(), "sendMsg", new String[]{"String"}, null);

        // 定义逻辑
        runner.addFunctionOfServiceMethod("是否新用户", new Test(), "isNewAcct", new Class[]{Integer.class}, null);
        runner.addFunctionOfServiceMethod("是否有手机号", new Test(), "isMobile", new Class[]{Integer.class}, null);

        // 定义规则
//        String express = "如果 (是否新用户(1)) 则 {赠送优惠券(1)} 否则 {赠送积分(1)} 如果(是否有手机号(1)) 则 {发送短信(\"欢迎您哦\")}";
        String express = "如果  (是否新用户(2)) 则 { 赠送优惠券(1)} 否则 { 赠送积分(1)} 如果 (是否有手机号(1)) 则 {发送短信(\"欢迎您哦\")}";
        DefaultContext<String, Object> context = new DefaultContext<>();
        Object execute = runner.execute(express, context, null, true, false);
        System.out.println(execute);
    }

    /**
     * 赠送优惠券
     *
     * @param num 优惠券
     */
    public static void sendCoupon(Integer num) {
        System.out.println("赠送优惠券啦:" + num);
    }

    /**
     * 赠送积分
     *
     * @param num 积分
     */
    public static void sendIntegral(Integer num) {
        System.out.println("赠送积分啦:" + num);
    }

    /**
     * 发送短信
     *
     * @param msg 短信
     * @return 内容
     */
    public String sendMsg(String msg) {
        System.out.println("发送短信啦:" + msg);
        return msg;
    }

    /**
     * 判断是否为新客户
     *
     * @param userType 类型
     * @return 结果
     */
    public boolean isNewAcct(Integer userType) {
        return userType == 1;
    }

    /**
     * 是否有手机号
     *
     * @param mobileType 类型
     * @return 结果
     */
    public boolean isMobile(Integer mobileType) {
        return mobileType == 1;
    }
}