drools 规则几个关键字

来源:互联网 发布:少儿英语 知乎 编辑:程序博客网 时间:2024/06/07 02:58
drools规则编写内置几个关键字drools语法关于关于规则执行互斥分组以及相关的关键字如下agenda-group:规则是否执行的分组,同一个分组的规则要么都执行要么都不执行salience:执行顺序优先级activation-group:互斥的规则分组,同一组的规则只有一条会被执行,其他不执行(事实对象修改被显示通知drools的除外)

标签agenda-group

用来对规则进行分组的标签 对于带有agenda-group的规则,如果所在分组中某个规则带有auto-focus标签,则分组包含的规则在规则引擎中会被执行;否则不会执行。对于没有agenda-group标签的规则,则不受到auto-focus标签的影响,会被执行。示例:

主函数

 public static void main(String[] args) {        KieServices kieServices = KieServices.Factory.get();        KieContainer kieContainer = kieServices.getKieClasspathContainer();        KieSession kieSession = kieContainer.newKieSession("testSession");        kieSession.setGlobal("results", Lists.newArrayList());        Map paramMap = Maps.newHashMap();        paramMap.put("key","3");        kieSession.insert(paramMap);        kieSession.fireAllRules();    }

规则组1

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule1-a"agenda-group "001"auto-focus    when            $param:Map(key==3)    then    System.out.println("testRule1-a");    results.add("break");endrule "testRule1-b"agenda-group "001"    when            $param:Map(key==3)    then    System.out.println("testRule1-b");    results.add("break");end

以下放入到第二个文件中

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule3"agenda-group "001"    when            $param:Map(key==3)    then    System.out.println("testRule3");    results.add("break");end

规则组2未加auto-focus

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule2-a"agenda-group "002"    when            $param:Map(key==3)    then    System.out.println("testRule2-a");    results.add("continue");endrule "testRule2-b"agenda-group "002"    when            $param:Map(key==3)    then    System.out.println("testRule2-b");    results.add("continue");end

第三组规则另一个带有auto-focus的分组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule"agenda-group "005"auto-focus    when            $param:Map(key==3)    then    System.out.println("testRule5");    results.add("break");end

第四组规则,未加agenda-group

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule4"    when            $param:Map(key==3)    then    System.out.println("testRule4");    results.add("break");end

执行结果
这里写图片描述

可以看出
agenda-group为003的规则存在auto-focus,被执行,输出
testRule3
agenda-group为001的规则也存在auto-focus,被执行,输出
testRule1-a
testRule1-b
执行另一个带有auto-focus的分组
输出testRule5
最后执行不包含agenda-group标签的testRule4,输出
testRule4

salience

用来指定规则的执行顺序的优先级,数值越大优先级越高,执行顺序越靠前,默认值为0,可以为负数
例子:
第一组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule1-a"agenda-group "001"auto-focussalience 0    when            $param:Map(key==3)    then    System.out.println("testRule1-a");    results.add("break");endrule "testRule1-b"agenda-group "001"salience 50    when            $param:Map(key==3)    then    System.out.println("testRule1-b");    results.add("break");end
package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule3"agenda-group "001"auto-focussalience 20    when            $param:Map(key==3)    then    System.out.println("testRule3");    results.add("break");end

第二组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule2-a"agenda-group "002"salience 10    when            $param:Map(key==3)    then    System.out.println("testRule2-a");    results.add("continue");endrule "testRule2-b"agenda-group "002"salience 40auto-focus    when            $param:Map(key==3)    then    System.out.println("testRule2-b");    results.add("continue");end

第三组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule4"salience 20    when            $param:Map(key==3)    then    System.out.println("testRule4");    results.add("break");end

执行结果
这里写图片描述

可以看出,执行规则的顺序为按组执行,执行完001 这个group再执行002这个group,最后再执行没有分组的规则,并且优先级是按照组内的优先级执行,并不能跨组优先级

综上所述,执行的顺序是先按分组
1.被focus的agenda-group所包含的规则
2.然后没有agenda-group的规则

之后按每个分组内部的salience优先级顺序,先执行值大的规则,再执行值小的规则

关键字activation-group

同一个activation-group的规则是互斥的,只有一个会被执行。
(注意,如果被执行的规则存在调用insert,modify,update 等方法,互斥的唯一性将被打破,需要再次调用下一个规则,一直执行下去直到没有通知drools 事实对象被修改的规则(即不包含insert,modify,update 等方法),详细用例见触发规则重复执行)
示例:
规则代码一组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule1-a"agenda-group "001"auto-focusactivation-group "act001"salience 0    when            $param:Map(key==3)    then    System.out.println("testRule1-a");    results.add("break");endrule "testRule1-b"agenda-group "001"activation-group "act001"salience 50    when            $param:Map(key==3)    then    System.out.println("testRule1-b");    results.add("break");end

规则代码二组

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule2-a"agenda-group "002"auto-focusactivation-group "act001"salience 10    when            $param:Map(key==3)    then    System.out.println("testRule2-a");    results.add("continue");end

运行结果:
这里写图片描述

可以看出activation-group同为001的三个规则,只执行了一个。

触发规则重复执行

如果被执行的规则存在
update modify insert等修饰事实对象的操作
则有可能出现循环重复执行的情况

例子:
代码

package rules;import java.util.List;import java.util.Map;global java.util.List results;rule "testRule1-a"activation-group "act001"//no-loop true    when            $param:Map(key==3)    then    System.out.println(" testRule1-a");    $param.put("key",4);    update($param);    results.add("break");endrule "testRule2-a"//no-loop true    when            $param:Map(key==4)    then    System.out.println(" testRule2-a");    $param.put("key",5);    update($param);    results.add("continue");endrule "testRule1-b"activation-group "act001"//no-loop true    when            $param:Map(key==5)    then    System.out.println(" testRule1-b");    $param.put("key",3);    update($param);    results.add("break");end

执行结果,无限死循环
这里写图片描述

解决方案就是去掉一个update() 断开循环链

0 0
原创粉丝点击