drools中的条件 when

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drools中的条件 when相关的知识,希望对你有一定的参考价值。

参考技术A

此篇文章主要记录一下 drools 中的模式( patterns )和约束( constraints )以及 when 中条件的写法。

1、匹配的条件结果需要是 true 或者 false 。
2、 Person(age < 20) 和 Person(getAge() < 20) 是等价的,但是 推荐第一种写法 。
3、 Person(age < 20) 默认会调用 getAge() 方法,如果该方法不存在则会调用 age() 方法,如果还不存在,则抛出异常。
4、 Drools engine 会缓存调用期间的匹配结果以提高效率,因此我们的 getter 方法,不要有状态。

.( <constraints> ) 将这些属性访问器分组到嵌套对象,以获得更易读的规则

在嵌套模式中,我们可以使用 <type>#<subtype> 语法强制转换为子类型并使父类型的 getter 用于子类型。

注意看上方的 car#BMWCar ,这个是将 car 转换成 BMWCar 类型来使用。

在有状态的 kie session 中,需要谨慎的使用 嵌套属性 。因为 Drools engine 的工作内存不知道任何嵌套值,也不会检测它们何时更改。

isChild() 方法不应该修改 fact 的状态,因为 drools引擎 为了提高工作效率,会将调用期间的结果进行缓存,如果修改了状态,可能将会导致匹配的结果不准。

上面2种写法是一样的。

1、在顶级字段约束中 , 的性能是要高于 && 的。
2、 && 优先于 || , && 和 || 两者都优先 , 。
3、不可在复合表达式中嵌入 , ,比如: Person((name != null , age < 20) , car != null) 这是错误的写法,需要将 , 换成 && 符号。

在 drools 中默认的日期格式为 dd-mmm-yyyy ,此处我们通过设置系统变量 drools.dateformat 修改成 yyyy-MM-dd HH:mm:ss 格式。

后期我们可以使用 $p 和 $age , $p 表示当前规则运行时,工作内存中匹配到的 Person 对象, $age 表示匹配到这个对象的 age 属性,一般绑定变量以 $ 开头,和 fact 的属性区分开。

这样写不清晰,而且执行效率不高。

的结果是不一样的, $age1 的结果是 $age2 的结果的2倍。

使用 .() 运算符将属性访问器分组到嵌套对象

以上2种写法是同一个意思

在嵌套模式中,我们可以使用 <type>#<subtype> 语法强制转换为子类型并使父类型的 getter 用于子类型。

car#BMWCar 指的是将 car 转换成 BMWCar 类型。

当我们的属性存在嵌套的时候,使用 !. 可以避免空指针异常。

1、List操作-按照索引访问

2、map操作-按照键操作

Person(map["key1"] == "value1") 中的这个 map 是 Person 的一个字段是 map

这些操作符和Java中的用法一致。
<, <=, >, >= 这些操作符,如果是用在 Date 类型的字段,则 < 表示before,对于 String 类型的字段,则按照自然顺序排序比较

Person(age >= 18 && age <= 25) 和 Person(age (>= 18 && <= 25)) 是相等的。

contains :包含; not contains :不包含。

1、验证一个 Array 或 Collection 是否包含某个指定字段的值(可以是 常量 也可以是 变量 )。
2、也可以是 String 类型的字段是否包含某个值(可以是 常量 也可以是 变量 )。

hobbyList :List类型的字段。
name 或 car.name :String类型的字段。

从上方的例子中可以看到:
hobbyList contains "打篮球" :"打篮球"是一个常量字符串。
hobbyList not contains nam :"name"是一个动态变量,从Person中获取。

验证某个字段是否是 Array 或 Collection 的一员。 Array 或 Collection 必须是可变的。

判断某个值是否在某一组值中

下表列出了 DRL 运算符从 高到低 的优先级。

drl 中支持的规则条件元素比较多,此处 讲解部分 关键字字的用法。

or 也支持好几种写法,此处列出一种写法。和 java 中的 or 用法一致

与工作内存中的 Fact 进行匹配,只会在第一次匹配时触发,不会触发多次,如果和多个模式一起使用,则需要使用 () 。

简单理解: 假设我工作内存中一次插入了5个 Person 对象,如果 exists 匹配到了,那么只会执行一次,不会执行5次。

规则内存中不存在这个对象时,触发规则。

比如: not Person() 表示规则内存中没有 Person 这个 Fact 对象时触发。

使用它来指定模式的数据源。 这使 Drools 引擎能够对不在工作内存中的数据进行推理。 数据源可以是绑定变量的子字段,也可以是方法调用的结果。 用于定义对象源的表达式是任何遵循常规 MVEL 语法的表达式。 因此,from 元素使您能够轻松地使用对象属性导航、执行方法调用以及访问映射和集合元素。

如果 Person 的 hobbyList 是一个比较大的集合,那么推荐将 hobbyList 这个插入到 kie session 中,来提高性能。

Using from with lock-on-active rule attribute can result in rules not being executed . You can address this issue in one of the following ways:

包含 from 子句的模式后面 不能跟以括号开头的另一个模式 。 此限制的原因是 DRL 解析器将 from 表达式读取为“来自 $l (String() or Number())”,它无法将此表达式与函数调用区分开来。 最简单的解决方法是将 from 子句括在括号中 ,如以下示例所示:

使用它来定义与模式的数据源相对应的入口点或事件流 。 此元素通常与 from 条件元素一起使用。 您可以为事件声明一个入口点,以便 Drools 引擎仅使用来自该入口点的数据来评估规则。 您可以通过在 DRL 规则中引用它来隐式声明一个入口点,或者在您的 Java 应用程序中显式声明它。

Order() 从上方的规则文件中可以,这个 Order() 对象是从 order-entry-point 这个地方来的。而不是别的地方来的。

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-when

1、 https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#drl-rules-WHEN-con_drl-rules

以上是关于drools中的条件 when的主要内容,如果未能解决你的问题,请参考以下文章

drools执行完某个规则后终止别的规则执行

Drools学习笔记2—Conditions / LHS 匹配模式&条件元素

drools when写条件判断时能加循环吗?我有多个条件要进行判断,而且条件的数量未知。

Drools 速成教程(上)

Java规则引擎Drools急速入门

规则引擎Drools介绍使用及SpringBoot整合Drools