drools 规则几个关键字

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");
end

rule "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");
end

rule "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-focus
salience 0
    when
            $param:Map(key==3)
    then

    System.out.println("testRule1-a");
    results.add("break");
end

rule "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-focus
salience 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");
end

rule "testRule2-b"
agenda-group "002"
salience 40
auto-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-focus
activation-group "act001"
salience 0
    when
            $param:Map(key==3)
    then

    System.out.println("testRule1-a");
    results.add("break");
end

rule "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-focus
activation-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");
end

rule "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");
end

rule "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() 断开循环链

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值