Drools规则属性,高级语法

本文详细介绍了Drools规则的各种属性,如enabled、dialect、salience等,以及高级语法,如global、query、function等。强调了如何防止规则执行中的死循环,如何设置规则执行优先级,并探讨了有状态和无状态session的使用场景。
摘要由CSDN通过智能技术生成

目录

规则属性  attributes

enabled属性

dialect属性

salience属性

no-loop属性

lock-on-active属性

activation-group属性

agenda-group属性

auto-focus属性

timer属性

date-effective属性

date-expires属性

Drools高级语法

global全局变量

query查询

function函数

条件-LHS加强

复合值限制in/not in

条件元素eval

条件元素not

条件元素exists

规则继承

结果-RHS

insert方法

update方法

在更新数据时需要注意防止发生死循环。

modify方法

retract/delete方法

RHS加强

halt

getWorkingMemory

getRule

规则文件编码规范(重要)

有状态session和无状态session


规则属性  attributes

前面我们已经知道了规则体的构成如下:

rule "ruleName"
    attributes
    when
        LHS
    then
        RHS
end

Drools中提供的属性如下表(部分属性):

enabled属性

enabled属性对应的取值为true和false,默认值为true。

用于指定当前规则是否启用,如果设置的值为false则当前规则无论是否匹配成功都不会触发

package rules
import com.mashibing.drools.entity.AttributesEnabledEntity

/*
 用于测试Drools 属性:enabled
*/

//测试enabled
rule "rule_attributes_enabled"
    enabled false
    when
        AttributesEnabledEntity(num > 10)
    then
        System.out.println("规则rule_attributes_enabled触发");
end

dialect属性

dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。

注:mvel是一种基于java语法的表达式语言。

虽然mvel吸收了大量的java语法,但作为一个表达式语言,还是有着很多重要的不同之处,以达到更高的效率,比如:mvel像正则表达式一样,有直接支持集合、数组和字符串匹配的操作符。

 除了表达式语言外,mvel还提供了用来配置和构造字符串的模板语言。

mvel2.x表达式包含以下部分的内容:属性表达式,布尔表达式,方法调用,变量赋值,函数定义

salience属性

salience属性用于指定规则的执行优先级,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。

drl文件内容如下:

package rules
import com.mashibing.drools.entity.AttributesSalienceEntity

/*
 用于测试Drools 属性:salience
*/

rule "rule_attributes_salience_1"
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_1 触发");
end

rule "rule_attributes_salience_2"
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_2 触发");
end

rule "rule_attributes_salience_3"
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_3 触发");
end

通过控制台可以看到,由于以上三个规则没有设置salience属性,所以执行的顺序是按照规则文件中规则的顺序由上到下执行的。接下来我们修改一下文件内容:

package rules
import com.mashibing.drools.entity.AttributesSalienceEntity

/*
 用于测试Drools 属性:salience
*/

rule "rule_attributes_salience_1"
    salience 10
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_1 触发");
end

rule "rule_attributes_salience_2"
    salience 20
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_2 触发");
end

rule "rule_attributes_salience_3"
    salience 1
    when
        AttributesSalienceEntity(flag == true)
    then
        System.out.println("规则 rule_attributes_salience_3 触发");
end

通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。

建议在编写规则时使用salience属性明确指定执行优先级。

no-loop属性

no-loop属性用于防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使当前规则再次被激活从而导致死循环。取值类型为Boolean,默认值为false。测试步骤如下:

第一步:编写规则文件

package rules
import com.mashibing.drools.entity.AttributesNoLoopEntity

/*
 用于测试Drools 属性:no-loop
*/

rule "rule_attributes_noloop"
    //no-loop true
    when
        $attributesNoLoopEntity:AttributesNoLoopEntity(num > 1)
    then
        update($attributesNoLoopEntity)
        System.out.println("规则 rule_attributes_noloop 触发");
end




第二步:编写单元测试

    @Test
    public void test(){
        KieSession kieSession = kieBase.newKieSession();
        AttributesNoLoopEntity attributesNoLoopEntity = new AttributesNoLoopEntity();
        attributesNoLoopEntity.setNum(20);

        kieSession.insert(attributesNoLoopEntity);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

通过控制台可以看到,由于我们没有设置no-loop属性的值,所以发生了死循环。接下来设置no-loop的值为true再次测试则不会发生死循环。

lock-on-active属性

lock-on-active这个属性,可以限制当前规则只会被执行一次,包括当前规则的重复执行不是本身触发的。取值类型为Boolean,默认值为false。测试步骤如下:

第一步:编写规则文件

```java
package rules
import com.mashibing.drools.entity.AttributesLockOnActiveEntity

/*
 用于测试Drools 属性:lock-on-active
*/

rule "rule_attributes_lock_on_active_1"
    no-loop true
    when
        $attributesLockOnActiveEntity:AttributesLockOnActiveEntity(num > 1)
    then
        update($attributesLockOnActiveEntity)
        System.out.println("规则 rule_attributes_lock_on_active_1 触发");
end

rule "rule_attributes_lock_on_active_2"
    no-loop true
    lock-on-active true
    when
        $attributesLockOnActiveEntity:AttributesLockOnActiveEntity(num > 1)
    then
        update($attributesLockOnActiveEntity)
        System.out.println("规则 rule_attributes_lock_on_active_2 触发");
end

```



第二步:编写单元测试

```java
    @Test
    public void test(){
        KieSession kieSession = kieBase.newKieSession();
        AttributesLockOnActiveEntity attributesLockOnActiveEntity = new AttributesLockOnActiveEntity();

        attributesLockOnActiveEntity.setNum(20);

        kieSession.insert(attributesLockOnActiveEntity);

        kieSession.fireAllRules();
        kieSession.dispose();
    }
```

no-loop的作用是限制因为modify等更新操作导致规则重复执行,但是有一个限定条件,是当前规则中进行更新导致当前规则重复执行。而不是防止其他规则更新相同的fact对象,导致当前规则更新,lock-on-active可以看作是no-loop的加强版,不仅能限制自己的更新,还能限制别人的更新造成的死循环。

activation-group属性

activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。

第一步:编写规则文件



```java
package rules
import com.mashibing.drools.entity.AttributesActivationGroupEntity

/*
 用于测试Drools 属性: activation-group
*/

rule "rule_attributes_activation_group_1"
    activation-group "customGroup"
    when
        $attributesActivationGroupEntity:AttributesActivationGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_activation_group_1 触发");
end

rule "rule_attributes_activation_group_2"
    activation-group "customGroup"
    when
        $attributesActivationGroupEntity:AttributesActivationGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_activation_group_2 触发");
end

```



第二步:编写单元测试

```java
	@Test
    public void test(){
        KieSession kieSession = kieBase.newKieSession();
        AttributesActivationGroupEntity attributesActivationGroupEntity = new AttributesActivationGroupEntity();
        attributesActivationGroupEntity.setNum(20);

        kieSession.insert(attributesActivationGroupEntity);

        kieSession.fireAllRules();
        kieSession.dispose();
    }
```

通过控制台可以发现,上面的两个规则因为属于同一个分组,所以只有一个触发了。同一个分组中的多个规则如果都能够匹配成功,具体哪一个最终能够被触发可以通过salience属性确定。

agenda-group属性

agenda-group属性为议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。

第一步:编写规则文件



```java
package rules
import com.mashibing.drools.entity.AttributesAgendaGroupEntity

/*
 用于测试Drools 属性: agenda-group
*/

rule "rule_attributes_agenda_group_1"
    agenda-group "customAgendaGroup1"
    when
        $attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_agenda_group_1 触发");
end

rule "rule_attributes_agenda_group_2"
    agenda-group "customAgendaGroup1"
    when
        $attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_agenda_group_2 触发");
end


rule "rule_attributes_activation_group_3"
    agenda-group "customAgendaGroup2"
    when
        $attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_activation_group_3 触发");
end

rule "rule_attributes_agenda_group_4"
    agenda-group "customAgendaGroup2"
    when
        $attributesAgendaGroupEntity:AttributesAgendaGroupEntity(num > 1)
    then
        System.out.println("规则 rule_attributes_agenda_group_4 触发");
end

```



第二步:编写单元测试

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值