Drools开源业务规则引擎(二)- Drools规则语言(DRL)
文章目录
- 1.DRL文件的组成:
- 2.package
- 3.import
- 4.function
- 5.query
- 6.declare
- 7.global
- 8.rule
- 8.1.规则属性
- 8.2.LHS
- 8.2.1.语法格式
- 8.2.2.运算符优先级
- 8.2.3.特殊的运算符
- 1.`matches`, `not matches`
- 2.`contains`, `not contains`
- 3.`memberOf`, `not memberOf`
- 4.`in`, `notin`
- 5.`soundslike`
- 6.`str`
- 7.`from`
- 8.3.RHS
- 8.3.1.`set`
- 8.3.2.`modify`
- 8.3.3.`update`
- 8.3.4.`insert`
- 8.3.5.`delete`
- 8.3.6.`drools.halt()`
1.DRL文件的组成:
在官方文档中(链接地址 https://docs.drools.org/7.74.1.Final/drools-docs/html_single/index.html#_droolslanguagereferencechapter),DRL的组成如下:
packageimportfunction // Optionalquery // Optionaldeclare // Optionalglobal // Optionalrule "rule name"// Attributeswhen// Conditionsthen// Actions
endrule "rule2 name"...
以上内容,只是梳理了DRL文件中组成的元素及其顺序(顺序非强制性要求,这是这样便于内容阅读)。
2.package
类似于 Java
中的 package
,声明规则的唯一命名空间(包)。包必须有一个名称空间,并使用包名称的标准 Java
约定进行声明;即没有空格,这与允许空格的规则名称不同。根据元素的顺序,它们可以以任何顺序出现在规则文件中,但package
语句除外,它必须位于文件的顶部。在任何情况下,分号都是可选的。
任何规则属性(见“规则属性”一节)也可以在包级别编写,取代该属性的默认值。修改后的默认值仍可能被规则中的属性设置所替换。
示例
// 带分号
package com.test;
// 不带分号
package com.test
3.import
类似于 Java
中的 import
。DRL文件中在规则中需要导入使用的对象的完全限定路径和类型名称。Drools引擎自动从与DRL包同名的Java
包和Java.lang
包中导入类。
示例
// 不需要导入,已自动导入
// import java.lang.String;import com.a.b.DroolsObject;
4.function
类似于 Java
中的 method
。可以将重复代码或者逻辑性代码封装成一个函数,或者将工具/辅助类中的静态方法导入为函数,然后在规则LHS/RHS部分中按名称使用该函数。
示例
// 导入静态方法/函数
import static org.example.applicant.MyFunctions.hello;// 函数1
function boolean ageJudge(Integer i){if (i > 10){return true;} else {return false;}
}// 使用函数
rule "age"
enabled true
wheneval(ageJudge(10));
then
end
5.query
查询在工作内存中相关的事实对象。查询的名称对于 KieBase
是全局的,因此对于该项目中的所有其他规则的查询必须是唯一的。ksession.getQueryResults("name")
获取查询结果,其中“name”是查询名称。
示例
package drools.drl// 导入输入类型
import com.ahao.project.input.UserIn;
global com.ahao.project.output.UserOut output;query "age>10"$in:UserIn(age > 10)
end
获取结果
QueryResults queryResults = kieSession.getQueryResults("age>10");
Iterator<QueryResultsRow> iterator = queryResults.iterator();
while (iterator.hasNext()) {QueryResultsRow next = iterator.next();log.info("查询结果:{}",next.get("$in"));
}// [main] INFO DroolsTest2 - 查询结果:UserIn(age=35)
// [main] INFO DroolsTest2 - 查询结果:UserIn(age=45)
6.declare
声明类型。用于在DRL声明一个新的类型。
示例
package drools.drlimport com.ahao.project.input.UserIn// 声明一个Person类型
declare Personname:Stringage:Integer
endrule "age"
enabled true
when$in:UserIn(age > 10)
thenPerson person = new Person();person.setAge($in.getAge());person.setName("命中规则");System.out.println(person);
end
结果
7.global
全局变量。DRL文件中的全局变量通常为规则提供数据或服务,如在then中使用的应用程序服务(service),并从规则返回数据。
示例
// 全局变量的定义
global com.ahao.project.output.UserOut output;
// 可以有多个
// global com.ahao.project.output.UserOut output222;
注意:
执行规则时,需要先设置全局变量对象
kieSession.setGlobal("output", output); // 然后再 kieSession.fireAllRules()
8.rule
rule语法结构如下图
8.1.规则属性
属性 | 默认值 | 描述 |
---|---|---|
salience | 0 | 规则优先级。在同一个 activation-group 中,具有较高优先级(值越大)的规则优先执行 示例: salience 10 |
enabled | true | 是否启用该规则 示例: enabled true |
date-effective | null | 只有当前日期时间在 date-effective 属性之后时,才能激活该规则 示例: date-effective "4-Sep-2018" |
date-expires | null | 只有当前日期时间在 date-expires 属性之前时,才能激活该规则 示例: date-expires "4-Oct-2018" |
no-loop | false | 是否可循环。某些情况下(update函数等),规则可以被再次激活 示例: no-loop true |
agenda-group | default | 议程组。对议程进行分区,以提供对规则组的更多执行控制。只有获得焦点的议程组中的规则才能被激活。 示例: agenda-group "GroupName" |
activation-group | null | 激活组。一个激活组只能激活一个规则,即使其他规则体的LHS部分仍然为true也不会再被执行。 示例: activation-group "GroupName" |
duration | null | 以毫秒为单位的持续时间。如果规则条件当前满足,则在该持续时间之后可以激活规则。 示例: duration 10000 |
timer | null | 调度器。“时间间隔”或“cron”计时器定义 示例: timer ( cron:* 0/15 * * * ? ) (every 15 minutes) |
calendar | null | 用于调度规则的 Quartz calendar 示例: calendars "* * 0-7,18-23 ? * *" (exclude non-business hours) |
auto-focus | false | 自动获取焦点,仅适用于议程组内的规则。选择该选项后,下次激活规则时,会自动将焦点指定给规则所分配的议程组: 示例: auto-focus true |
lock-on-active | false | 仅适用于规则流组或议程组内的规则。选择该选项后,下次规则的规则流组变为活动状态或规则的议程组收到焦点时,在规则流组不再活动或议程组失去焦点之前,无法再次激活规则。是no-loop属性的更强版本。 示例: lock-on-active true |
ruleflow-group | null | 规则流组。只有被关联的规则流激活这个组时,规则才能激活 示例: ruleflow-group "GroupName" |
dialect | mvel | 用来定义规则中要使用的语言类型 示例: dialect "java" |
8.2.LHS
规则的when部分(也称为Left Hand Side(LHS))包含执行操作必须满足的条件。
8.2.1.语法格式
格式
// 格式如下(对象名称前的 $ 非必需的)
when$对象名称:事实对象的全限定类名(字段约束)// 如果已经import了事实对象的全限定类名
when$对象名称:事实对象的类名(字段约束)
示例
// 示例1
when$p:com.test.Person(age > 10 || name == "jack")// 示例2
import com.test.Person;
whenp:Person(age > 10 || name == "jack")
8.2.2.运算符优先级
操作类型 | 符号 | Notes |
---|---|---|
嵌套或(null-safe)属性访问 | . , .() , !. | 不是标准的Java语义 |
List 或者 Map 访问 | [] | 不是标准的Java语义 |
约束绑定(类型绑定) | : | 不是标准的Java语义 |
乘积 | * , / ,% | |
加减 | + , - | |
位运算 | >> , >>> , << | |
关系型 | < , <= , > , >= , instanceof | |
等于 | == != | 使用equals() 和!equals() 语义,非标准Java same 和not same 语义 |
非短路 AND | & | |
非短路异运算 | ^ | |
非短路包含 OR | ` | ` |
逻辑运算 AND | && | |
逻辑运算 OR | ` | |
三元运算符 | ? : | |
逗号分隔 AND | , | 不是标准的Java语义 |
运算符
==
使用null-safe equals()
语义,而不是通常的equals
语义。例如,Person(firstName=="John")
类似于java.util。Objects.equals(person.getFirstName(),“John”)
,并且由于"John"
不为null
,所以该模式也类似于"John".equals(person.get-FirstName)
。
以上运算符都基本上类似java中的运算符。接下会介绍一些特殊的运算符。
8.2.3.特殊的运算符
1.matches
, not matches
判断与指定的Java正则表达式匹配或不匹配。
示例
Person( country matches "(USA)?\\S*UK" )
2.contains
, not contains
数组或集合字段是否包含指定值。可以使用这些运算符来代替String.contains()和!String.contents()。
示例
// 姓名包含王
Person( name contains "王" )
// 假设一个人有多个手机号,phones:List<String>
// 手机号不包含12345678901
Person( phones not contains "12345678901" )
3.memberOf
, not memberOf
是否为数组或集合的成员。
示例
// 手机号不包含12345678901
Person( "12345678901" not memberOf phones)
4.in
, notin
指定约束中要匹配的多个可能值(复合值限制)。
示例
// 名称为 jack 或者 mary
Person( name in ("jack","mary"))
5.soundslike
验证单词是否具有与给定值几乎相同的发音(英语发音)。
示例
// firstName "Jon" or "John":
Person( firstName soundslike "John" )
6.str
验证字符串字段是以指定值开始,以指定值结束,或者字符串的长度。
示例
// 消息的以"R1"开始
Message( msg str[startsWith] "R1" )// 消息的以"R2"结尾
Message( msg str[endsWith] "R2" )// 消息的长度为17
Message( msg str[length] 17 )
7.from
获取数据源。
示例
// 从模式绑定(变量)中获取数据源
rule "rule1"
whenPerson( $personAddress : address )Address( zipcode == "11110" ) from $personAddress
then
end// 从图形符号中获取数据源
rule "rule1"
when$p : Person()$a : Address( zipcode == "23920W" ) from $p.address
then
end// 从迭代器中获取数据源
rule "rule1"
when$order : Order()$item : OrderItem( value > 100 ) from $order.items
then
end
8.3.RHS
规则的then部分(也称为 Right Hand Side(RHS))。当满足规则的when部分时要执行的操作。操作的主要目的是在Drools引擎的工作内存中插入、删除或修改数据。有效的规则操作是小的、声明性的和可读的。如果需要在规则操作中使用命令式或条件式代码,请将规则划分为多个更小、更具声明性的规则。
8.3.1.set
赋值。
示例
$person.setName("jack");
8.3.2.modify
针对某个事实进行修改,并将更改通知Drools引擎。
语法
modify ( <fact-expression> ) {<expression>,<expression>,...
}
示例
modify( Person ) {setAge( 100 ),setName ( "nick" )
}
8.3.3.update
指定要更新的字段和整个相关事实,并将更改通知Drools引擎。
语法
update ( <object, <handle> )
update ( <object> )
示例
person.setAge( 100 );
update( person );
8.3.4.insert
将一个新的事实插入Drools引擎的工作内存中。
语法
insert( new <object> );
示例
insert( new Person() );
8.3.5.delete
从Drools引擎中删除对象。
语法
delete( <object> );
示例
delete( person );
8.3.6.drools.halt()
终止规则执行。
示例
rule "end_rule"
enabled true
when
thendrools.halt();
end
相关文章:

Drools开源业务规则引擎(二)- Drools规则语言(DRL)
文章目录 1.DRL文件的组成:2.package3.import4.function5.query6.declare7.global8.rule8.1.规则属性8.2.LHS8.2.1.语法格式8.2.2.运算符优先级8.2.3.特殊的运算符1.matches, not matches2.contains, not contains3.memberOf, not memberOf4.in, notin5.soundslike6…...

PTA甲级1005:Spell It Right
错误代码: #include<iostream> #include<vector> #include<unordered_map> using namespace std;int main() {unordered_map<int, string> map {{0, "zero"}, {1, "one"}, {2, "two"}, {3, "three&qu…...

Vue笔记11-Composition API的优势
Options API存在的问题 使用传统Options API中,新增或者修改一个需求,就需要分别在data,methods,computed里修改,而这些选项分布在代码的各个地方,中间还穿插着其他Optional API,如果代码量上来…...

rancher管理多个集群
一、rancher部署 单独部署到一台机器上,及独立于k8s集群之外: 删除所有yum源,重新建yum源: # 建centos7.9的yum源 # cat CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the …...

某大会的影响力正在扩大,吞噬了整个数据库世界!
1.规模空前 你是否曾被那句“上有天堂,下有苏杭”所打动,对杭州的湖光山色心驰神往?7月,正是夏意正浓的时节,也是游览杭州的最佳时期。这座古典与现代交融的城市将迎来了第13届PostgreSQL中国技术大会。作为全球数据库…...

PostgreSQL主从复制:打造高可用数据库架构的秘籍
PostgreSQL主从复制:打造高可用数据库架构的秘籍 在当今的数字化时代,数据的安全性和可靠性是企业最为关注的问题之一。PostgreSQL作为一种强大的开源关系型数据库管理系统,提供了多种高可用性解决方案,其中主从复制是最为常用的…...

Fast R-CNN(论文阅读)
论文名:Fast R-CNN 论文作者:Ross Girshick 期刊/会议名:ICCV 2015 发表时间:2015-9 论文地址:https://arxiv.org/pdf/1504.08083 源码:https://github.com/rbgirshick/fast-rcnn 摘要 这篇论文提出了一…...

视觉语言模型:融合视觉与语言的未来
1. 概述 视觉语言模型(Vision-Language Models, VLMs)是能够同时处理和理解视觉(图像)和语言(文本)两种模态信息的人工智能模型。这种模型结合了计算机视觉和自然语言处理的技术,使得它们能够在…...

【CSAPP】-linklab实验
目录 实验目的与要求 实验原理与内容 实验步骤 实验设备与软件环境 实验过程与结果(可贴图) 实验总结 实验目的与要求 1.了解链接的基本概念和链接过程所要完成的任务。 2.理解ELF目标代码和目标代码文件的基本概念和基本构成 3.了解ELF可重定位目…...

UE C++ 多镜头设置缩放 平移
一.整体思路 首先需要在 想要控制的躯体Pawn上,生成不同相机对应的SpringArm组件。其次是在Controller上,拿到这个Pawn,并在其中设置输入响应,并定义响应事件。响应事件里有指向Pawn的指针,并把Pawn的缩放平移功能进行…...

代码随想录Day69(图论Part05)
并查集 // 1.初始化 int fa[MAXN]; void init(int n) {for (int i1;i<n;i)fa[i]i; }// 2.查询 找到的祖先直接返回,未进行路径压缩 int.find(int i){if(fa[i] i)return i;// 递归出口,当到达了祖先位置,就返回祖先elsereturn find(fa[i])…...

53-1 内网代理3 - Netsh端口转发(推荐)
靶场还是用上一篇文章搭建的靶场 :52-5 内网代理2 - LCX端口转发(不推荐使用LCX)-CSDN博客 一、Netsh 实现端口转发 Netsh是Windows自带的命令行脚本工具,可用于配置端口转发。在一个典型的场景中,如果我们位于公网无法直接访问内网的Web服务器,可以利用中间的跳板机通过…...

四、(1)网络爬虫入门及准备工作(爬虫及数据可视化)
四、(1)网络爬虫入门及准备工作(爬虫及数据可视化) 1,网络爬虫入门1.1 百度指数1.2 天眼查1.3 爬虫原理1.4 搜索引擎原理 2,准备工作2.1 分析爬取页面2.2 爬虫拿到的不仅是网页还是网页的源代码2.3 爬虫就是…...

2024华为OD机试真题-分月饼-(C++/Python)-C卷D卷-200分
2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++) 题目描述 中秋节,公司分月饼,m 个员工,买了 n 个月饼,m ≤ n,每个员工至少分 1 个月饼,但可以分多个,单人分到最多月饼的个数是 Max1 ,单人分到第二多月饼个数是 Max2 ,Max1 - Max2 ≤ 3 ,单人分到第 n - 1…...

Git 查看提交历史
Git 查看提交历史 Git 是一个强大的版本控制系统,它允许开发人员跟踪代码的变化,并与其他人协作。了解如何查看提交历史对于理解项目的发展和维护代码库至关重要。本文将详细介绍如何使用 Git 查看提交历史,包括不同的命令和选项,…...

力扣双指针算法题目:快乐数
目录 1.题目 2.思路解析 3.代码展示 1.题目 . - 力扣(LeetCode) 2.思路解析 题目意思是将一个正整数上面的每一位拿出来,然后分别求平方,最后将这些数字的平方求和得到一个数字,如此循环,如果在此循环中…...

【Tools】了解人工通用智能 (AGI):未来的智能体
什么是人工通用智能 (AGI)? 人工通用智能(Artificial General Intelligence,AGI)是指一种能够理解、学习和应用知识,具有像人类一样广泛和通用的认知能力的智能系统。与专门处理特定任务的人工智能(AI&…...

华媒舍:8种网站构建推广方法全揭密!
网站构建成为了推广宣传和宣传品牌的关键一环。对于新手,搭建和营销推广网站有可能是一项全新的挑战。下面我们就为大家介绍8种网站搭建和营销推广技巧,帮助你在这些方面取得成功。 1.选择适合自己的网站构建平台选择合适的网站构建平台针对构建一个成功…...

【Scrapy】 深入了解 Scrapy 下载中间件的 process_exception 方法
准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 🎵 陈慧娴《傻女》 Scrapy 是…...

DevEco Studio无法识别本地模拟器设备的解决方法
目录 场景 解决办法 方式1 方式2 场景 有很多小伙伴遇到过安装了手机模拟器, 但是开发工具设备栏不识别手机设备的问题, 如下图,明明模拟器都安装了,并启动, 但为什么设备栏不显示呢? 解决后的截图,应该是这样(其实跟 android 类似 )...

EN-SLAM:Implicit Event-RGBD Neural SLAM解读
论文路径:https://arxiv.org/pdf/2311.11013.pdf 目录 1 论文背景 2 论文概述 2.1 神经辐射场(NeRF) 2.2 事件相机(Event Camera) 2.3 事件时间聚合优化策略(ETA) 2.4 可微分的CRF渲染技术…...

2407C++,从构生成协议文件
原文 protobuf会根据proto文件生成c对象及其序化/反序化方法,而iguana的struct_pb则是以结构为核心,编译期反射来生成序化/反序化代码. 有人提出能不能按proto文件输出结构呢,这样就可给其它语言用了,很好建议,实现起来也比较简单. protobuf是从proto文件到c对象,而struct_p…...

遗传算法求解TSP
一、基本步骤 遗传算法求解旅行商问题(TSP)的一般步骤如下: 编码: 通常采用整数编码,将城市的访问顺序表示为一个染色体。例如,假设有 5 个城市,编码为[1, 3, 5, 2, 4],表示旅行商的…...

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【明文导入密钥(C/C++)】
明文导入密钥(C/C) 以明文导入ECC密钥为例。具体的场景介绍及支持的算法规格 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 指定密钥别名keyAlias。 密钥别名的最大长度为64字节。 封装密钥属性集和密钥材料。通过[OH_Huks_I…...

视频汇聚/安防监控/GB28181国标EasyCVR视频综合管理平台出现串流的原因排查及解决
安防视频监控系统/视频汇聚EasyCVR视频综合管理平台,采用了开放式的网络结构,能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理,视频汇聚EasyCVR平台支持设备…...

TypeError: Cannot read properties of null (reading ‘nextSibling‘)
做项目用的Vue3Vite, 在画静态页面时,点击菜单跳转之后总是出现如下报错,百思不得其解。看了网上很多回答,也没有解决问题,然后试了很多方法,最后竟然发现是template里边没有结构的原因。。。 原来我的index.vue是这样…...

解决 npm intasll 安装报错 Error: EPERM: operation not permitted
Node.js安装及环境配置完成之后 npm install express -g 安装全局的模块报错提示没有权限operation not permitted mkdir 错误编号4048: 其原因是当前用户操作该目录权限不足,当以管理员身份运行cmd,再执行npm install express -g 是不会报权…...

redis实用技能
为什么要使用redis及其使用场景 大部分场景是应对高并发高性能场景才会使用,就是访问量已经超过mysql所能承受的,需要做缓存,帮助mysql分流。或者一些复杂查询,mysql执行很慢没法优化,可以做缓存提速(做缓存)做认证服务的时候需要存储用户的session信息,使用redis数据有…...

AcWing 1260:二叉树输出
【题目来源】https://www.acwing.com/problem/content/1262/【题目描述】 树的凹入表示法主要用于树的屏幕或打印输出,其表示的基本思想是兄弟间等长,一个结点的长度要不小于其子结点的长度。 二叉树也可以这样表示,假设叶结点的长度为 1&…...