当前位置: 代码迷 >> 综合 >> drools 规则引擎使用手记
  详细解决方案

drools 规则引擎使用手记

热度:4   发布时间:2024-01-31 19:15:35.0

drools 规则引擎使用手记

文章目录

  • drools 规则引擎使用手记
    • 规则的组成部分:
      • 规则结构:
      • 包(Package)
      • 导包 (import)
      • 全局变量(global)
      • 函数(Function)
      • 规则属性
      • 运算符“&&”,“ ||”,“ ,”优先级
      • 支持嵌套的表达式
      • 数据生命周期设置

使用说明:

? 通过页面自定义动态规则,实现气象数据的动态阈值监测告警,当阈值被触发的时候,后台的规则就会做出相应的反应,然后提示触发的是什么规则,已经触发的规则阈值是多少,数据主要来源于实时的气象站点和预报数据。

规则的组成部分:

规则结构:

rule "name"attributeswhenLHSthenRHS
end

通常,规则文件中是不需要标点符号的。即使是规则名“name”上的双引号也是可选的。attributes展示规则的执行方式,也是可选的。LHS是规则的条件部分,遵循一个固定的语法规则,在下面的内容会详细介绍。RHS通常是一个可以本地执行的代码块。 一个规则在一个包中必须具有独一无二的名字。如果在一个DRL文件中重复定义两个相同名字的规则,在加载的时候就会报错。如果向包中添加一个名字已经存在的规则,该规则会覆盖掉之前的同名规则。如果一个规则命中存在空格符,最好使用双引号将规则名包括起来。
规则的属性不是必须的,且属性最好写成一行。
规则中的LHS在关键字when的后面,同样的,RHS应该在关键字then的后面,规则最后以关键字end结尾。另外,规则不准嵌套。

包(Package)

package是一系列rule或其他相关构件如imports, globals的容器。这个成员之间相互关联,一个package代表了一个命名空间,其中的每个rule的名字都是唯一的,package名字本身就是命名空间,与实际的文件和文件夹没有任何关系。常见的结构是,一个文件包含多个rule的文件就定义成一个包。以下的线路图表明了一个包中包含的所有组成元素。

image-20200715093101174

需要注意的是,一个包必须有一个命名空间,且其声明必须遵守Java命名规范。package语句必须出现在包的首行,其他组成部分的出现顺序无关紧要。其中package语句结尾的分号;是可选的。

导包 (import)

? Drools文件中的import语句功能与Java中的import语句功能类似。使用import时,必须指定对象的全称限定路径和类型名。Drools会自动导入Java相同名字的包中的所有类,也会导入java.lang.*

全局变量(global)

? global用于定义全局变量。用于使应用对象对一系列规则有效。通常,用于向规则提供全局的数据和服务,特别是一些用于规则序列的应用服务,如日志、规则序列中累加的值等。全局的变量是不会插入Woking Memory中的,另外,全局变量不要用于建立规则的条件部分,除非它是一个不会改变的常量。全部变量的改变不会通知到规则引擎,规则引擎不跟踪全局变量的变化,因为他们并没有加入到Woking Memory中。全局变量使用不当,会产生很多不可思议的结果。如果多个包中同时定义了相同标识符的全局变量,那么这些全局变量必须是相同类型,并会引用一个相同的全局值。全局变量并不是用来在规则间共享数据,而且最好不要用于在规则间共享数据。规则总是对工作内存的状态产生推理和反应,因此,如果想在规则之间传递数据,可以将这些数据作为facts传入工作内存。因为规则引擎并不会关心和跟踪这些全局变量的变化。

函数(Function)

? function提供了一种在规则源文件中插入语义代码的方式,与在普通Java类中不同。他们需要帮助类,否则不能做任何事情。(实际上,编译器会针对这些句子自动产生帮助类。)在规则中使用函数的最主要优点就是你可以把所有逻辑放在一个地方,你可以根据需要更改这些函数的逻辑。函数通常用于在规则的then部分调用某些动作,特别是一些经常被用到的而传入参数不一样的动作。
典型的function格式如下:

function String hello(String name) {return "Hello "+name+"!";
}静态java 方法调用public static ArrayList isRuleSid(String ruleSceneIdRuleId) {ArrayList arrayList = new ArrayList();if (ruleSid.containsKey(ruleSceneIdRuleId)) {arrayList = ruleSid.get(ruleSceneIdRuleId);}return arrayList;}在规则中导入 :import function com.kedalo.service.impl.RuleInfoServiceImpl.isRuleSid;在规则中调用:isRuleSid("rule_1_39") 

规则属性

规则属性显式地声明了对规则行为的影响,有些规则属性很简单,有些规则属性是复杂的子系统的一部分,如规则流。为了从Drools中获得更多东西,我们需要确保对每一个规则属性均有正确的认识。
常用的规则属性有如下:

  • no-loop
    • 默认值:false
    • type: Boolean
      当规则序列更改了一个fact,会导致该规则会被重新触发,以至于产生一个无限循环。当设置为true时,当前规则只会被激活一次。
  • ruleflow-group
    • 默认值:N/A
    • type: String
      ruleflow是Drools的特色之一,可以让你自己控制规则的命中。同一个ruleflow-group中的所有规则只有当该组激活时才能被命中。
  • lock-on-active
    • 默认值:false
    • type: Boolean
      不管何时ruleflow-groupagenda-group被激活,只要其中的所有规则将lock-on-active设置为true,那么这些规则都不会再被激活,不管一开始怎么更新,这些匹配的规则都不会被激活。这是no-loop属性的增强,因为这些变化现在不仅仅是规则自身的变化。
  • salience
    • 默认值:0
    • type: Integer
      任何规则都有一个默认为0的salience属性,该属性可以为0,正数和负数。salience表示规则的优先级,值越大其在激活队列中的优先级越高。Drools支持使用动态的salience,可以使用一个包含动态约束变量的表达式来表示。如下所示
      Dynamic Salience
rule "Fire in rank order 1,2,.."salience( -$rank )whenElement( $rank : rank,... )then...
end
  • agenda-group
    • 默认值:MAIN
    • type: String
      agenda-group允许用户将Agenda分割成多个部分以提供更多的运行控制。
  • auto-focus
    • 默认值:false
    • type: Boolean
      当一个规则被激活时auto-focus为true,而且该规则的agenda-group还没有focus,当该agenda-groupfocus时,允许该规则潜在命中。
  • activation-group
    • 默认值:N/A
    • type: String
      属于同一个activation-group的规则会进行唯一命中。也就是说同一个activation-group中的规则,只要有一个命中,其他的规则都会被取消激活状态,这样这些规则就不会被命中。
  • dialect
    • 默认值:as specified by the package
    • type: String
      dialect用于指明规则中使用的代码的语言种类,目前支持两种语言,“java"或"mvel”。
  • date-effective
    • 默认值:N/A
    • type: String (包含日期和时间)
      当前系统时间在date-effective之后,该规则才会被激活。
  • date-effective
    • 默认值:N/A
    • type: String (包含日期和时间)
      当前系统时间在date-effective之后,该规则不会再被激活。
  • duration
    • 默认值:无
    • type: long (包含日期和时间)
      duration用于表示一个规则在一定时间之后才会被命中,如果它还是激活状态的话。

运算符“&&”,“ ||”,“ ,”优先级

尽管&&和,运算符具有相同的语义,但它们的解析具有不同的优先级:&&运算符优先于||运算符。&&和||运算符都在运算符,之前。请参阅下面的运算符优先级列表。

逗号运算符应该是顶级约束的首选,因为它使约束更容易阅读,并且Drools引擎通常能够更好地优化它们。逗号运算符不能嵌入到复合约束表达式中

支持嵌套的表达式

Person( address.houseNumber == 50 )// this is the same as:
Person( getAddress().getHouseNumber() == 50 )

数据生命周期设置

  1. 未测试

image-20200724170344489