参考自:
Drools 文档 — 官方文档
Drools 7.66.0 — 官方文档
.
.
.
说明:目录采用格式:官方文档编号 + 我定义的标题
1.3.1 安装和使用
2022-03-02 15:46
drools jar dependency
2.3 DMN
DMN:Decision Model and Notation(决策模型标记)
BPMN:Business Process Model and Notation(业务流程模型标记)
交替规则 DMN
》》》jar 部署 kie-server上,远程访问
7.3.0 改为新版测试(Drools workbench)
可Rest API 访问(账号,密码)
3.1.1 KIE
KIE 是 Drools 和 jBPM 的共享核心。
它为构建、部署和利用资源提供了统一的方法和编程模型。
KIE:Knowledge Is Everything(知识就是一切)
jBPM:Java Business Process Management(Java 业务流程管理)
3.1.2 KIE生命周期
使用KIE系统的不同方面,或生命周期,无论是Drools还是jBPM,通常可以分为以下几个方面:
- Author
使用 UI 隐喻创作知识,例如:DRL、BPMN2、决策表、类模型。
Build
将编写的知识构建为可部署的单元。
对于KIE来说,这个单位是一个JAR。Test
在将KIE知识部署到应用程序之前进行测试。Deploy
将单元部署到应用程序可以利用(消耗)它们的位置。(drl打包到 jar里面,我们也可以加载到 drl 文件)
KIE 使用 Maven 风格的存储库。Utilize(使用)
加载 JAR 以提供应用程序可以与之交互的 KIE 会话 (KieSession)。
KIE 通过 KIE 容器 (KieContainer) 在运行时公开 JAR。
运行时与之交互的 KieSessions 是从 KieContainer 创建的。Run
系统交互与KieSession,通过API。Work
用户交互与KieSession,通过命令行或UI。Manage
管理任何KieSession或KieContainer。
总结图:
3.1.3 集群支持
7.4后支持集群(运行时)
3.1.4 资产(不同场景)
只有 DRL 灵活,可集成 IDE、语法。
(Drools Rule Language)
3.1.5 储存和构建
1、项目版本控制选项 (Git)
1 | 内置 git(workbench) |
2、项目管理选项 (Maven)
1 | 内置 maven(workbench) |
3、项目构建选项
1 | 内置kjar(workbench) |
3.1.6 部署
2022-03-02 16:24
1、部署 kie-server(kjar)
2、嵌入Java(JVM)
(KIE API 配置 KieScanner,定期更新 KieContainer)
3.1.7 测试
1、kie-server(REST)
2、嵌入Java(JVM)
3、workbench(决策)
》》》需要创建资产 assets(DRL文件,实体类,场景测试…)
3.1.8 部署架构
1、kie-server + wildfly(最适用于 DMN)
2、IDE + kie-server(wildfly):DRL、电子决策表、DMN
3、IDE + Java(我们)
图示:
3.2.1 最小化部署
KIE 使用默认值来最小化配置量。空的 kmodule.xml 是最简单的配置。必须始终有一个 kmodule.xml 文件,即使是空的,因为它用于发现 JAR 及其内容。
Maven 可以“mvn install”将 KieModule 部署到本地机器,本地机器上的所有其他应用程序都使用它。或者它可以“mvn deploy”将 KieModule 推送到远程 Maven 存储库。构建应用程序将拉入 KieModule 并在此过程中填充本地 Maven 存储库。
我画的:
1 |
|
两种部署:
1、maven依赖jar(单版本)
kie扫描类路径 kmodule.xml(所有依赖的jar)
2、动态添加(并行版本)
3.2.2 org.kie.api.builder
3.2.2.1 创建和构建 Kie 项目
不同于其他 maven 项目
特别之处:resources/META-INF/kmodule.xml
1 |
|
默认值:有默认 KieBase(空 kmodule.xml)
1 | org.kie.api.runtime.KieContainer |
3.2.2.2 kmodule.xml 文件
2022-03-02 18:27
1 | KieBase |
1 | 2022-03-02 18:43 |
2022-03-02 19:11
前面讲的是基于 kmodule.xml classpath 创建 KieContainer。
我们项目(计分卡)【需要 KieContainer 创建 KieBase】
1 |
|
3.2.2.3 maven构建
1 | kjar |
想用 @kie.api.Position,Java类中。(需要加 kie-api 依赖)
》》》尽量 kjar 轻量,不依赖其他。
没有maven插件(jar)
》》》all 放入 resources jar 中。
运行时,加载jar,构建资源。
(编译出错时,KieContainer 创建出来是 null)。
》》》编译放到运行中做(不建议这样,建议 maven 插件)。
3.2.2.4 编程式
1 | KieBase |
编程式构建 kmodule.xml:
1 | // 创建 xxxModel (编程式 XML 配置) |
检查编译结果是最佳实践。
报告 3 种不同严重性的KieBuilder编译结果:ERROR、WARNING 和 INFO。
ERROR 表示项目编译失败,在这种情况下,没有生成KieModule,也没有向KieRepository添加任何东西。
WARNING和INFO结果可以被忽略,但可用于检查。
1 | KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll(); |
2022-03-02 20.59
再说一遍
1 |
|
2022-03-02 21.16
OSGi(开放服务网关协议,Open Service Gateway Initiative)
有时,例如在 OSGi 环境中,KieBase需要解析不在默认类加载器中的类型。
在这种情况下,有必要KieBaseConfiguration使用附加的类加载器创建一个,并在从它KieContainer创建一个新的类加载器时将其传递给KieBase。
1 | // 使用自定义 ClassLoader 创建新的 KieBase |
3.2.3.2 KieSessions 和 KieBase 修改
KieSessions 后面更详细地讨论。
KieBase创建并返回KieSession对象,它可以选择保留对这些对象的引用。
(KieBase修改,KieSession可感知,将把修改应用于会话)
当KieBase修改发生时,这些修改将应用于会话中的数据。该引用是弱引用,也是可选的,由布尔标志控制。
Drools WorkBench 测试
2022.03.03 06.10
1 | wb: |
3.2.3.3 KieScanner
2022.03.03 10.08
1 | KieScanner(扫描) |
3.2.3.4 maven范围依赖
1 | [1.0.1] 等同于 1.0.1 |
3.2.3.5 Settings.xml 和远程存储库设置
setting.xml 三个位置
远程 maven 库
1 | KieContainer |
3.2.4.3 KieRuntime
set Global
注册 channel
Global
1 | 设置:kieSession.setGlobal |
3.2.4.4 Event、Listener
支持多种 Event(xxxEvent)
BeforeMatchFiredEvent
AfterMatchFiredEvent
添加删除监听
DefaultAgendaEventListener
DebugRuleRuntimeEventListener
3.2.4.5 KieRuntimeLogger
1 | console |
3.2.4.6 Commands、CommandExecutor
1 | CommandExecutor => 无状态(包含 finally dispose,一次性的) |
3.2.4.7 无状态
1 | 封装 KieSession,不扩展 |
execute流程(一次性)
1 | 创建 KieSession |
1 | Globals |
3.2.4.9 持久化 和 事务
JPA:Java Persistence Api
JTA:Java Transaction Api
3.2.5 部署架构
3.2.6 构建、部署
2022-03-03 14:03
1 | 3.2.6.1 |
3.2.7 可执行模型(嵌入式)
2022-03-03 14.33
1 | Drools 中 Rule 默认 kie-maven-plugin 构建 |
3.2.7.1 修改禁用
mvn clear install -DgenerateModel=△
- YES_WITHDRL:(默认)生成与原始项目中的 DRL 文件对应的可执行模型,并将 DRL 文件添加到生成的 KJAR 以用于文档目的(无论如何,KIE 库都是从可执行模型构建的)。
- YES:生成与原项目中的DRL文件对应的可执行模型,并从生成的KJAR中排除DRL文件。
- NO:不生成可执行模型。
编程式:
1 | buildAll(); NO |
3.2.7.2 启动可执行模型
2022-03-03 15.34
drools 7.39版本后,默认 kie-maven-plugin 构建。
不使用可执行模型
1、不使用 kie-maven-plugin 插件
2、不依赖 drools-model-compiler
如果依赖 drools-model-compiler,可执行模型编译成 Drools内部数据结构。
方便 drools 引擎执行。
1 | KieScanner(更新 KieContainer) |
4 Drools规则引擎
2022-03-03 17:07
1 | Drools规则引擎: |
4.1 KieSession
2022-03-03 17:28
1 | KieSession 创建 |
无状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
无状态
=> 无数据保存
=> 不使用推理对事实迭代更改
无状态:场景
=> 校验:某个人是否可以申请贷款
=> 计算:计算贷款
=> 路由和过滤:东西分类,或事件发送
=> 例如:18岁以下不能考驾照($可选,为了区分变量 和 属性 Field)
execute(再说一次)
=> 创建KieSession
=> 添加数据,执行命令
=> fireAllRules();
=> dispose(); finally块中执行
无状态
=> 3中可迭代执行
=> 三种全局变量 Globals
=> command;
=> out作为results;
=> getGlobals();(注意并发)有状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15有状态
=> 推断对fact迭代更改
=> 调用后也会保存(数据 facts)
=> 记得dispose(); 避免内存泄漏
场景
=> 监控:股票市场,自动化购买
=> 诊断:运行故障诊断或医疗诊断流程
=> 物流:包裹跟踪和交付准备
=> 确保合规:验证市场交易合法性
=> 例如:火灾、洒水器、警报
=> 结果保留,后续调用
=> insert => fireAllRules...
=> delete => fireAllRules...KieSession Pool
2022-03-03 18:40
1 | 会话池:解决避免瓶颈 |
4.2 Drools引擎基本功能
1 | 基本功能 |
2022-03-03 19:22
1 | insert() |
4.2.1 政府身份证案例
2022-03-03 19:58
1 | Rule的 坏写法 |
4.2.2 fact 相等模式
1 | identity |
4.3 Drools引擎执行控制
1 | 新 Rule -> 进入 Working memory,可能匹配并执行。 |
2022-03-03 20.44
4.3.1 salience
2022-03-03 20.52
1 | Rule的salience属性: |
4.3.2 agenda-group
1 | agenda-group |
4.3.3 activation-group
2022-03-04 07.22
相同属性 activation-group 的 Rule 被称为一个激活组
一个激活组只执行1条Rule。
满足Rule条件后,其他Rule会从 agenda 中删除。
4.3.4 执行模式和线程安全
Passive mode 被动模式:(默认)fireAllRules();
Active mode 主动模式:fireUnitHalt();
1 | 多线程同时使用: |
4.3.5 Fact传播模式
1 | Lazy 懒加载(默认) |
4.3.6 Agenda Filter
true:执行Rule
false:不执行
例如:执行以 “Test” 结尾的 Rule。
1 | ksession.fireAllRules( new RuleNameEndsWithAgendaFilter( "Test" ) ); |
4.3.7 Rule Units
规则单元是一组数据源、全局变量和DRL规则,它们共同作用于特定的目的。
您可以使用规则单元将规则集划分为更小的单元,将不同的数据源绑定到这些单元,然后执行单个单元。
规则单元是规则分组DRL属性(例如用于执行控制的规则议程组或激活组)的一种增强的替代方法。
当您希望协调规则执行,以便一个规则单元的完整执行触发另一个规则单元的开始时,规则单元是很有帮助的
(使用 agenda-group 也可以实现动态激活 RHS 中 setFocus)
4.4.1 Phreak 算法
1 | 简介: |
4.4.2 Rule基本配置
1 | 1、异常处理器 |
4.5 复杂事件处理 CEP
2022-03-04 09.14
CEP(complex event processing 复杂事件处理)
声明fact、事件、滑动窗口。
元数据标签、cloud/stream,event运算符,query查询。
4.7 监听器
监听器原则:尽可能单纯,无交互,无状态(会阻塞 Drools)。
agenda:执行一次前中后
runtime:增删改
4.8 性能优化
1 | 1、无状态应用启动 时序性模式(参考4.4.2) |
5 Rule语法规则
DRL(Drools Rule Language 流口水规则语言)
LHS(Left Hand Side 左手边)
RHS(Right Hand Side 右手边)
1 | .drl 文件定义业务规则(rule) |
5.1 DRL Rules 语法
2022-03-04 10.30
1 | package // 放在顶部 |
5.1.1 package
1 | 1、包名要唯一 |
5.1.2 import
1 | 同 Java(;可省略) |
5.1.3 function
为了定义语义抽象(参数不同的情况下定义)。
或 import 静态方法,在 then 中用。
5.1.4 query
工作内存中查询 Fact
kSession.getQueryResults(“query name”);
=> List 可迭代
(了解)
5.1.5 declare
2022-03-04 11.10
1 | 新 Fact:简化版 entity Object |
5.1.6 Global 全局变量
1 | 提供数据、服务 |
5.1.7 Rule属性(重点)
1 | salience |
——————-
分隔符
上面是一开始用笔写在本子上的,再用键盘打印的。
下面的是直接,用电脑做的笔记。
5.1.8 WHEN(LHS)
重写
5.1.8.1 模式和约束
Patterns and constraints
DRL 规则条件中的模式是 Drools 引擎要匹配的段。一个模式可以潜在地匹配插入到 Drools 引擎工作内存中的每个事实。模式还可以包含约束以进一步定义要匹配的事实。
getter 方法
下面二者是相同的效果。
默认 age 或调用其 getAge() 方法,因为它遵循标准的 JavaBeans 规范。1
2
3
4
5Person( age == 50 )
// This is the same as the following getter format:
Person( getAge() == 50 )fallback 方法
如果 getter 方法不存在,或执行 另外 Fallback 方法。1
2
3
4
5Person( age == 50 )
// If `Person.getAge()` does not exist, the compiler uses the following syntax:
Person( age() == 50 )属性嵌套
1
2
3
4
5Person( address.houseNumber == 50 )
// This is the same as the following format:
Person( getAddress().getHouseNumber() == 50 )但不推荐那么做。
如果更新工作内存中 Address 的话,也要把 Person 给更新。
(只更新 Address 的话,Drools引擎只能感知到工作内存中 Address 更新,是感知不到 Person 更新的。)
不要在调用前改变Fact
Fact 状态不应该在调用之前被改变。除非每次改变 Fact 都更新工作内存。1
2
3
4Person( incrementAndGetAge() == 10 ) // Do not do this.
Person( System.currentTimeMillis() % 1000 == 0 ) // Do not do this.等等 比较
1
2
3
4
5
6
7== 等同于
// java.util.Objects.equals
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
- 强制类型转换
数值计算,“10” 或强制转为 int 类型 10。1
Person( age == "10" ) // "10" is coerced to 10
逗号等同于 and
1
2
3
4
5// Person 年龄至少50岁,体重至少80公斤:
Person( age > 50, weight > 80 )
// Person 年龄50岁以上,体重80公斤以上,身高2米以上:
Person( age > 50, weight > 80, height > 2 )优先级
&& 与 and
表达的意思是一样的,但是优先级不同。&& 与 ||
的优先级要大于逗号,
的。
但是,逗号,
具有更好的 drools 引擎性能 和 可读性。
注意:不要在复合约束条件中使用逗号,
来表示and,应该使用 &&
1 | // 不要使用以下格式: |
5.1.8.2 绑定变量
推荐使用 $variable
来命名(不强制)。
1 | rule "simple rule" |
绑定变量到属性
1
2
3// //两名同龄的人:
Person( $firstAge : age ) // 绑定
Person( age == $firstAge ) // 约束表达式混合绑定
虽然支持,但不推荐那么用。会影响 Drools引擎的复杂评估。1
2
3
4
5// 不要使用以下格式:
Person( $a : age * 2 < 100 )
// 请使用以下格式:
Person( age * 2 < 100, $a : age )两倍绑定,应使用括号
1
Person( $a : (age * 2) )
5.1.8.3 嵌套和内联
嵌套情况下,可以使用 .(<constraints> )
。
例如:
1 | Person( name == "mark", address.city == "london", address.country == "uk" ) |
井号 内联类型转换
1
2
3
4
5
6
7
8// 子类型名称内联转换:
Person( name == "mark", address#LongAddress.country == "uk" )
// 全限定类名的内联转换:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )
// 多个内联转换:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )instanceof 类型判断
1
2// 如果无法进行内联转换(例如,如果instanceof返回false),则考虑评估false。
Person( name == "mark", address instanceof LongAddress, address.country == "uk" )
5.1.8.4 Date类型
默认情况下,Drools 引擎支持日期格式dd-mmm-yyyy
。(例如:"27-Oct-2009"
)
也可以设置系统变量来自定义设置。drools.dateformat="dd-mmm-yyyy hh:mm"
。
drools.defaultlanguage
您还可以通过使用和系统属性更改语言区域设置来自定义日期格式drools.defaultcountry
(例如,泰国的区域设置设置为drools.defaultlanguage=th
和drools.defaultcountry=TH
)。
1 | Person( bornBefore < "27-Oct-2009" ) |
5.1.8.5 自动装箱和原始类型
Drools 尝试使用原始类型保存,若是 Object 类型,需要进行装箱。
在评估的时候,也会强制转为可能的类型。因此,原始类型可以作为 Object 来进行比较。
5.1.8.6 约束运算符
分组访问
.()
1
2
3
4
5
6// 未分组的属性访问器:
Person( name == "mark", address.city == "london", address.country == "uk" )
// 分组属性访问器:
// 句点前缀点 . 将嵌套对象约束与方法调用区分开来。
Person( name == "mark", address.( city == "london", country == "uk") )内联类型转换
#
1
2
3
4
5
6
7
8// 子类型名称内联转换:
Person( name == "mark", address#LongAddress.country == "uk" )
// 全限定类名的内联转换:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )
// 多个内联转换:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )
- 非空判断
.!
1
2
3
4
5Person( $streetName : address!.street )
// 这在内部重写如下:
Person( address != null, $streetName : address.street )
List索引,Map键
[]
1
2
3
4
5// 等同于 `childList(0).getAge() == 18`:
Person(childList[0].age == 18)
// 等同于 `credentialMap.get("jdoe").isValid()`:
Person(credentialMap["jdoe"].valid)可比较
对具有自然顺序的属性使用这些运算符。这些属性仅适用于可比较的属性。< <= > >=
1
2
3Person( birthDate < $otherBirthDate ) // Date字段,< 运算符表示before
Person( firstName < $otherFirstName ) // String字段,运算符表示按字母顺序排列 before不等于
== !=
1
2
3
4
5
6
7Person( firstName == "John" )
// 这类似于以下格式:
java.util.Objects.equals(person.getFirstName(), "John")
"John".equals(person.getFirstName())
1 | Person( firstName != "John" ) |
1 | == 等同于 |
条件组合
&& ||
1
2
3
4
5
6
7
8// 简单缩写组合关系条件使用单一 `&&`:
Person(age > 30 && < 40)
// 使用分组的复杂缩写组合关系:
Person(age ((> 30 && < 40) || (> 20 && < 25)))
// 将缩写组合关系与约束连接词混合:
Person(age > 30 && < 40 || location == "london")正则表达式
matches not matches
这些运算符仅适用于String属性。
如果您matches对一个null值使用,则结果评估始终为false。
如果您not matches对一个null值使用,则结果评估始终为true。
与在 Java 中一样,您编写为文字的正则表达式String必须使用双反斜杠\\
进行转义。
1 | // 匹配 |
- 是否包含
Array或Collection是否包含指定值。
也可以用于String类型:String.contains()和!String.contains()约束检查。
为了向后兼容,excludes
运算符是受支持的同义词not contains
contains not contains
Collection
1 | // Collection with a specified field: |
String
1 | // Sting literal with a specified field: |
- 是否存在…里面
可以理解为 SQL 中的in not in
memberOf not memberOf
1
2
3FamilyTree( person memberOf $europeanDescendants )
FamilyTree( person not memberOf $europeanDescendants )
发音相同
该运算符使用 Soundex 算法。soundslike
1
2// Match firstName "Jon" or "John":
Person( firstName soundslike "John" )字符串开头,结尾,长度
str[startsWith | endsWith | length]
1
2
3
4
5
6
7
8// Verify what the String starts with:
Message( routingValue str[startsWith] "R1" )
// Verify what the String ends with:
Message( routingValue str[endsWith] "R2" )
// Verify the length of the String:
Message( routingValue str[length] 17 )在…里面
等同于 SQL 中的in not in
in notin
1
2
3
4
5Person( $color : favoriteColor )
Color( type in ( "red", "blue", $color ) )
Person( $color : favoriteColor )
Color( type notin ( "red", "blue", $color ) )
5.1.8.7 运算符优先级
5.1.8.8 规则条件关键字
and
使用它来将条件组件分组为逻辑合取。支持中缀和前缀and。您可以使用括号明确地对模式进行分组()。
默认情况下,所有列出的模式都与and未指定连词时结合使用。1
2
3
4
5
6
7
8
9
10
11
12// 中缀 `and`:
Color( colorType : type ) and Person( favoriteColor == colorType )
// 中缀 `and` 分组:
(Color( colorType : type ) and (Person( favoriteColor == colorType ) or Person( favoriteColor == colorType ))
// 前缀 `and`:
(and Color( colorType : type ) Person( favoriteColor == colorType ))
// 默认隐式 `and`:
Color( colorType : type )
Person( favoriteColor == colorType )
声明绑定不要使用 and,可以使用 or。
例如下面的错误案例:
1 | // 编译错误: |
or
使用它来将条件组件分组为逻辑析取。支持中缀和前缀or。您可以使用括号明确地对模式进行分组()。
您也可以将模式绑定与 一起使用or,但每个模式必须单独绑定。1
2
3
4
5
6
7
8// 中缀 `or`:
Color( colorType : type ) or Person( favoriteColor == colorType )
// 中缀 `or` 分组:
(Color( colorType : type ) or (Person( favoriteColor == colorType ) and Person( favoriteColor == colorType ))
// 前缀 `or`:
(or Color( colorType : type ) Person( favoriteColor == colorType ))
带有 pattern 绑定的示例:
下面的 $pensioner
只能绑定其中一个。
1 | $pensioner : (Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 )) |
exists
使用它来指定必须存在的事实和约束。
如果您将此元素与多个模式一起使用,请用括号将模式括起来()。
注意:此选项仅在第一次匹配时触发,而不是后续匹配。
1 | exists Person( firstName == "John") |
not
使用它来指定不能存在的事实和约束。
如果您将此元素与多个模式一起使用,请用括号将模式括起来()。1
2
3
4
5
6not Person( firstName == "John")
not (Person( firstName == "John", age == 42 ))
not (Person( firstName == "John" ) and
Person( lastName == "Doe" ))forall
使用它来验证与第一个模式匹配的所有事实是否与所有剩余模式匹配。
当forall构造满足时,规则评估为true。
这个元素是一个作用域分隔符,所以它可以使用任何以前绑定的变量,但它内部的任何变量都不能在它之外使用。1
2
3
4
5
6
7
8rule "All full-time employees have red ID badges"
when
forall( $emp : Employee( type == "fulltime" )
Employee( this == $emp, badgeColor = "red" ) )
then
// True, all full-time employees have red ID badges.
// true,所有的全职员工都有红色的身份证
end
1 | rule "All employees have health and dental care programs" |
1 | rule "Not all employees have health and dental care" |
from
使用它来指定模式的数据源。
这使 Drools 引擎能够对不在工作内存中的数据进行推理。
数据源可以是绑定变量的子字段,也可以是方法调用的结果。
用于定义对象源的表达式是任何遵循常规 MVEL 语法的表达式。因此,该from元素使您能够轻松使用对象属性导航、执行方法调用以及访问映射和集合元素。
from $变量
1 | rule "Validate zipcode" |
from $变量.属性
1 | rule "Validate zipcode" |
from 迭代所有对象 $变量.集合属性
1 | rule "Apply 10% discount to all items over US$ 100 in an order" |
大集合放入变量
一个一个放入,不如直接把集合放入 KIE 的会话中去。
1 | when |
带有 lock-on-active 属性的 from
带有 lock-on-active 属性的 from 可能导致规则不被执行。可以使用以下方式解决:
1、当你插入所有Fact到工作内存,或 你使用嵌套引用在你的约束表达式的时候。尽量避免 from 元素的使用。
2、使用 modify() 块的时候,要放在 rule 条件的最后一句。
3、使用 ruleflow group 的时候,使用其中一个来管理另外一个的时候。要避免使用 lock-on-active 属性。
1 | rule "Assign people in North Carolina (NC) to sales region 1" |
from括号的配合
含from子句的pattern后面不能跟以括号开头的另一个pattern。
此限制的原因是 DRL 解析器将from表达式读取为”from $l (String() or Number())”,它无法将此表达式与函数调用区分开来。
最简单的解决方法是将from子句括在括号中:
1 | // 错误用法 |
entry-point
入口点,通常与 from 一起使用。
要在 java 中声明。
略。。。感觉没啥用。collect
收集。
可以使用任何 java.util.Collection 实现类。
例如:List、LinkedList和HashSet,或您自己的类。
(外可内用,内不可外用。)
collect外绑定变量可以在collect内用,collect内绑定变量不可以在collect外用。
1 | // 收集为 List |
1 | // 配合 from 使用 |
accumulate
积累。略。1
2
3
4
5
6
7
8
9
10
11
12
13
14格式:
accumulate( <source pattern>; <functions> [;<constraints>] )
Drools 引擎支持以下预定义accumulate函数。
这些函数接受任何表达式作为输入。
average
min
max
count
sum
collectList
collectSet
eval
条件元素eval本质上是一个包罗万象的元素,它允许执行任何语义代码(返回原始布尔值)。
这段代码可以引用规则包中规则条件和函数中绑定的变量。
过度使用会eval降低规则的声明性,并可能导致 Drools 引擎性能不佳。
虽然eval可以在模式中的任何地方使用,但它通常作为规则条件中的最后一个条件元素添加。
eval的实例不能被索引,因此效率不如字段约束。
然而,这使得它们非常适合用于函数返回值随时间变化的情况,这在 字段约束 中是不允许的。
1 | p1 : Parameter() |
1 | p1 : Parameter() |
5.1.8.9 OOPath 语法
OOPath 是 XPath 的面向对象的语法扩展,旨在浏览 DRL 规则条件约束中的对象图。
OOPath 使用来自 XPath 的紧凑表示法在处理集合和过滤约束时导航相关元素,特别适用于对象图。
5.1.9 THEN(RHS)
LHS => Rule Conditions
RHS => Rule Actions
RHS 的主要目的是在 Drools 引擎的工作内存中插入、删除或修改数据。
有效的RHS是小的、声明性的和可读的。
如果您需要在RHS中使用命令式或条件代码,最好是将规则划分为多个更小且更具声明性的规则。
1 | rule "Underage"// 未成年的 |
5.1.9.1 RHS 增删改方法
DRL 支持您可以在 DRL 规则操作中使用的以下规则操作方法。
您可以使用这些方法来修改 Drools 引擎的工作内存,而无需先引用工作内存实例。
DRL支持以下规则操作方法,您可以在DRL规则操作中使用它们。
您可以使用这些方法来修改Drools引擎的工作内存,而无需先引用工作内存实例。
这些方法充当Drools分发版中RuleContext类提供的方法的快捷方式。
set
直接修改工作内存Fact对象1
2// 使用它来设置字段的值。
set<field> ( <value> )
例如:
1 | // 设置贷款申请批准值的示例规则操作 |
modify
(推荐modify替代 update)
使用它来指定要为事实修改的字段并将更改通知 Drools 引擎。
此方法提供了一种结构化的事实更新方法。它将update操作与 setter 调用相结合以更改对象字段。1
2
3
4
5modify ( <fact-expression> ) {
<expression>,
<expression>,
...
}
例如:
1 | // 修改贷款申请金额和批准的示例规则操作 |
update
(推荐modify替代 update)
使用它来指定要更新的字段和整个相关事实,并将更改通知 Drools 引擎。
调用 update 之前,要调用set去修改这个事实。
为避免此添加步骤,请改用该modify方法(不进行流程的操控)。insert
使用它可以将一个新事实插入到Drools引擎的工作内存中,并根据需要定义结果字段和值。
1 | insert( new <object> ); |
例如:插入一个学生
1 | insert( new Student() ); |
insertLogical
使用它将一个新的Fact逻辑地插入到Drools引擎中。
Drools引擎负责对事实的插入和撤回进行逻辑判断。
在常规或规定的插入之后,必须显式地收回事实(retract)。
在逻辑插入之后,当插入事实的规则中的条件不再为真时,插入的事实将自动收回(retract)。
delete
(推荐delete替代 retract)
使用此属性从Drools引擎中删除对象。
(retract)
DRL也支持关键字retract并执行相同的操作,但是为了与关键字insert保持一致,DRL代码通常更倾向于delete。
1 | delete( <object> ); |
例如:
1 | delete( $student); |
5.1.9.2 RHS 其他方法
drools.getRule().getName()
返回当前触发规则的名称。drools.getMatch()
返回Match激活当前触发规则的那个。
它包含对日志记录和调试有用的信息,
=> 例如drools.getMatch().getObjects()返回对象列表,使规则能够以正确的元组顺序触发。
从drools变量中,您还可以获得对KieRuntime提供有用方法的引用以与正在运行的会话进行交互
drools.getKieRuntime().halt()
如果用户或应用程序先前调用了 ,则终止规则执行fireUntilHalt()。当用户或应用程序调用fireUntilHalt()方法时,Drools 引擎以active模式启动并评估规则,直到用户或应用程序显式调用halt()方法。否则,默认情况下,Drools 引擎在passive模式下运行并仅在用户或应用程序显式调用fireAllRules()方法时评估规则。drools.getKieRuntime().getAgenda()
返回对 KIE 会话的引用Agenda,进而提供对规则激活组、规则议程组和规则流组的访问。
例如:设置焦点 drools.getKieRuntime().getAgenda().getAgendaGroup( “CleanUp” ).setFocus();
还有
1 | drools.getKieRuntime().setGlobal(), ~.getGlobal(), ~.getGlobals(): 设置或检索全局变量。 |
5.1.9.3 do then if-else
略。
因为 drools 支持的是可读性,较小精悍的。
这种只作为扩展。
真想用行不行,肯定行,但不推荐。