背景:

最近上头让研究各种物流的运费计算,并获取最优配送物流方案,无意之间搜索到了QLExpress,它是阿里的一个组件,一种规则引擎的算法,QLExpress在阿里集团内部有很强的影响力,被广泛应用在电商场景中,在业务灵活多变的场景下常常需要规则引擎的支持。所以我就动手自己实现了一下

GitHub地址:https://github.com/alibaba/QLExpress

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

前端监控:www.webfunny.cn ;只需要简单几步,就可以搭建一套属于自己的前端监控系统,快来试试吧。(github:webfunny_monitor)

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、优势

QLExpress脚本引擎被广泛应用在阿里的电商业务场景,具有以下的一些特性:

  • 1、线程安全,引擎运算过程中的产生的临时变量都是threadlocal类型。
  • 2、高效执行,比较耗时的脚本编译过程可以缓存在本地机器,运行时的临时变量创建采用了缓冲池的技术,和groovy性能相当。
  • 3、弱类型脚本语言,和groovy,javascript语法类似,虽然比强类型脚本语言要慢一些,但是使业务的灵活度大大增强。
  • 4、安全控制,可以通过设置相关运行参数,预防死循环、高危系统api调用等情况。
  • 5、代码精简,依赖最小,250k的jar包适合所有java的运行环境,在android系统的低端pos机也得到广泛运用。

2、引入依赖的jar

<!-- QLExpress -->
<dependency>    <groupId>com.alibaba</groupId>   <artifactId>QLExpress</artifactId>    <version>${qlexpress.version}</version>
</dependency>
<qlexpress.version>3.2.0</qlexpress.version>

用到的版本是3.2.0

3、语法

操作符和java对象操作

//支持 +,-,*,/,<,>,<=,>=,==,!=,<>【等同于!=】,%,mod【取模等同于%】,++,--,
//in【类似sql】,like【sql语法】,&&,||,!,等操作符
//支持for,break、continue、if then else 等标准的程序控制逻辑
n=10;
for(sum=0,i=0;i<n;i++){
sum=sum+i;
}
return sum;//逻辑三元操作
a=1;
b=2;
maxnum = a>b?a:b;

和java语法相比,要避免的一些ql写法错误

  • 不支持try{}catch{}
  • 不支持java8的lambda表达式
  • 不支持for循环集合操作for (GRCRouteLineResultDTO item : list)
  • 弱类型语言,请不要定义类型声明,更不要用Templete(Map<String,List>之类的)
  • array的声明不一样
  • min,max,round,print,println,like,in 都是系统默认函数的关键字,请不要作为变量名

QL用法:

是否符合 = 1;运费 = 0;如果 (30 < 重量 ) 则
{    是否符合 = 0;    return 是否符合;}
最长边 = 长 > 宽 ? 长 : 宽;
最长边 = 最长边 > 高 ? 最长边 : 高;
最短边 = 长 < 宽 ? 长 : 宽;
最短边 = 最短边 < 高 ? 最短边 : 高;
中间边 = (长 + 宽 + 高) - 最长边 - 最短边;
围长 = (中间边 + 最短边) * 2 + 最长边;
如果 (围长 > 300) 则
{    是否符合 = 0;    return 是否符合;}
如果 (最长边 > 175) 则
{    是否符合 = 0;    return 是否符合;}

java代码调用:

public class DPDRuleTest {@Test    public void DPDRuleTest() throws Exception {List<String> ruleFileNames = new ArrayList<String>();      ruleFileNames.add("rule/GB/DPD/DPD_UK.ql");       for (int i = 0; i < ruleFileNames.size(); i++) {String script = getResourceAsStream(ruleFileNames.get(i));         ExpressRunner runner = new ExpressRunner(false, false);        runner.addOperatorWithAlias("如果", "if", null);           runner.addOperatorWithAlias("则", "then", null);          runner.addOperatorWithAlias("否则", "else", null);       IExpressContext<String, Object> context = new DefaultContext<String, Object>();      try {context.put("长", 20);              context.put("宽", 20);            context.put("高", 20);                context.put("重量", 10);               context.put("COUNTRY","IS");           runner.execute(script, context, null, true, false);         if (String.valueOf(context.get("是否符合")).equals("1")) {System.out.println("文件名称:" + ruleFileNames.get(i));            System.out.println("最长边:" + context.get("最长边"));                    System.out.println("中间边:" + context.get("中间边"));               System.out.println("最短边:" + context.get("最短边"));                   System.out.println("是否符合:" + context.get("是否符合"));       System.out.println("运费:" + context.get("运费"));                }} catch (Exception e) {e.printStackTrace();              //Assert.assertTrue(e.toString().contains("at line 7"));         }}}public static String getResourceAsStream(String path) throws Exception {InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);      if (in == null) {throw new Exception("classLoader中找不到资源文件:" + path);       }BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"));    StringBuilder builder = new StringBuilder();       String tmpStr = null;        while ((tmpStr = reader.readLine()) != null) {builder.append(tmpStr).append("\n");     }reader.close();       in.close();       return builder.toString();  }
}

各种规则定义QL:

规则ql文件

也可以把这些规则全都放到数据库字段里面保存起来,并且页面化,进行可配置操作,达到方便配置的效果。

如下就是我们项目中一个规则引擎表设计:

规则表

freight_rule:保存各种规则。

到此我们的规则引擎已经达到了业务需求,后期准备在进行扩展。

-----------------------------------------------------------------------------------------------------------------------------------

前端监控:www.webfunny.cn ;只需要简单几步,就可以搭建一套属于自己的前端监控系统,快来试试吧。(github:webfunny_monitor)

-----------------------------------------------------------------------------------------------------------------------------------

强大的QLExpress相关推荐

  1. c语言ql,QlExpress使用

    背景和特性 背景 由阿里的电商业务规则.表达式(布尔组合).特殊数学公式计算(高精度).语法分析.脚本二次定制等强需求而设计的一门动态脚本引擎解析工具. 在阿里集团有很强的影响力,同时为了自身不断优化 ...

  2. QLExpress基本语法

    QLExpress基本语法 一.背景介绍 由阿里的电商业务规则.表达式(布尔组合).特殊数学公式计算(高精度).语法分析.脚本二次定制等强需求而设计的一门动态脚本引擎解析工具. 在阿里集团有很强的影响 ...

  3. 规则引擎QLExpress表达式计算数学公式

    1.引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>QLExpress</a ...

  4. 聊聊 QLExpress 源码 (一)

    QLExpress是动态脚本引擎解析工具,由于工作环境中经常会遇到一些规则,但是不想硬编码到系统中!这样便会用类似规则引擎模块来将这些规则从业务剥离出去,而我们系统中的底层因为使用了QLExpress ...

  5. Drools和qlExpress对比

    Drools 和 QLExpress 是两个不同的规则引擎. Drools 是一个功能强大的商业规则引擎,可以帮助用户创建.维护和执行业务规则.它提供了多种工具来帮助用户管理规则,包括用于规则编写和测 ...

  6. 窗口键 键位码_键盘上这些被冷落的键位居然有这么强大的功能

    各位小伙伴们大家好啊,又到了达尔优外设小课堂时间了,今天呢,我们将为大家带来的是键盘上的功能区按键小科普,也就是我们常说的F区按键. F区按键 F1~F12这个区域的按键我们通常称为功能键,而F的意思 ...

  7. iterm2 主题_【超级实用】Iterm2 + ohmyzsh 打造强大的终端编辑器

    作者:AndrewHR 地址:http://mrw.so/4D1n7B 最终的效果图如下所示:使用iterm2配合oh-my-zsh的命令行,拥有语法高亮.命令自动补全.自动提示符.显示git仓库状态 ...

  8. sklearn库安装_没有依赖库也能跑机器学习模型!推荐一个强大工具m2cgen

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI m2cgen(Model 2 Code Generator)是一个轻量级代码生成器,它可以将训练好的机器学习模型转换成无需依赖库的本地代码. ...

  9. linux java 构建工具有哪些,Linux ant --强大的Java开发构建工具

    用途说明 ant严格说来,ant其实并非原生的Linux命令,但它是一个使用广泛.功能强大的跨平台构建工具程序,尤其是进行Java开发时,许多开源的Java项目都使用ant作为构建工具.ant命令一般 ...

最新文章

  1. 北大博士“最高荣誉”,出炉!
  2. 链表问题7——判断一个链表是否为回文结构(进阶)
  3. HTML中的进度条标签的应用progress
  4. Google 公司的 Java 语言编写规范
  5. 科大星云诗社动态20210309
  6. 案例精解:insert逻辑读暴增至20万,只因Oracle Recyclebin过大
  7. Nokia Imaging SDK滤镜使用入门
  8. 以软件开发周期来说明不同的测试的使用情况
  9. 一个ExtJs的最基本的mvc模式示例
  10. 支持向量机---SVM 最小二乘支持向量机---LSSVM
  11. 安卓pdf阅读器_想找可以安装APP的电子书阅读器?BOOX这几个型号可以选!
  12. bzoj 4134: ljw和lzr的hack比赛 sg函数+字典树合并
  13. pmp复习资料链接-2021.06.20考试(中培)
  14. 软件插件化,大势所趋新势力
  15. 电脑键盘部分按键失灵_键盘失灵个别字母不灵怎么处理_电脑键盘个别键没反应如何修复...
  16. php微信自动回复接口,微信接口自动回复
  17. mysql logs_MySQL Logs
  18. swell word
  19. Python字符串相关方法
  20. 南邮计算机科学专业自我鉴定,大学毕业个人自我鉴定范文

热门文章

  1. 为什么我们都要拼命赚钱
  2. Unity3d花屏处理
  3. JS 判断一个字符串中每个字母出现的次数
  4. 用python-plt.subplots画色块图
  5. 利用开源工具实现轻量级上网行为审计 来源ispublic com
  6. 写最好的Docker安装最新版MySQL8(mysql-8.0.31)教程(参考Docker Hub和MySQL官方文档)
  7. 网易云音乐歌曲评论爬虫(附源码)
  8. pygame飞机大战用精灵组(sprite)的层(layer)编写(二)BOSS登场了
  9. html为什么叫超文本标记语言,HTML(超文本标记语言)的内容和理解
  10. pytest框架精髓—fixture