4. DRL规则属性

519 阅读5分钟

规则属性介绍

每个规则都可以设置自己的一些属性,属性可以影响规则执行的一些行为,是每个规则特有的一部分。

1. enabled属性

enabled属性对应的取值为true和false,默认值为true。 用于指定当前规则是否启用,如果设置为false则当前规则无论是否匹配成功都不会触发。

rule "rule_comparison_notMemberOf"
	// 指定当前规则不可用,当前规则无论是否匹配成功都不会执行
    enabled false
    when
    	ComparisonOperatorEntity(names not memberof list)
    then
    	System.out.println("规则rule_comparison_notMemberOf触发")
end

2. dialect属性

dialect属性用于指定当前规则使用的语言类型,取值为java和mvel,默认值为java。 注:mvel是一种基于java语法的表达式语言。 mvel像正则表达式一样,由直接支持集合、数组和字符串匹配的操作符。 mvel还提供了用来配置和构造字符串的模板语言。 mvel表达式内容包括属性表达式,布尔表达式,方法调用,变量赋值,函数定义等。

rule "要求Student的age等于10岁用于删除"
	// 指定规则使用的方言
    dialect "java"
	// 指定当前规则不可用,当前规则无论是否匹配成功都不会执行
    enabled false
    when
    	ComparisonOperatorEntity(names not memberof list)
    then
    	System.out.println("规则rule_comparison_notMemberOf触发")
end

3. salience属性

salience属性用于指定规则的执行优先级,取值类型为Integer。数值越大越优先执行。每个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。 可以通过创建规则文件salience.drl来测试salience属性,内容如下:

package test.salience
rule "rule_1"
	salience 5
	when
    	eval(true) // 返回true,即当前规则匹配成功
    then
    	System.out.println("规则:rule_1触发了...")
end

rule "rule_2"
	salience 10
	when
    	eval(true) // 返回true,即当前规则匹配成功
    then
    	System.out.println("规则:rule_2触发了...");
end

rule "rule_3"
	salience 1
	when
    	eval(true) // 返回true,即当前规则匹配成功
    then
    	System.out.println("规则:rule_3触发了...");
end

4. no-loop属性

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

package testnoloop
import entity.Student

rule "rule_noloop"
	no-loop true // 使用no-loop来解决死循环问题
	when
    	$s:Student(age == 50)
    then
    	update($s); // 当更新对象时会重新触发规则,在这个时候如果没有no_loop就会触发死循环
    	System.out.println("规则:rule_noloop触发了...");
end

5. activation-group属性

activation-group属性时指激活分组,取值为String类型。具有相同分组名称的规则只能由一个规则被触发。
一般用作a,b规则,在执行中做规则切换
第一步:编写规则文件/resources/rules/activationgroup.drl package testactivationgroup /*

  • 在规则文件用于测试activation-group属性 /*
rule "rule_activationgroup_1"
	activation-group "mygroup"
    when
    then
    	System.out.println("规则rule_activationgrou_1触发");
end

rule "rule_activationgroup_2"
	activation-group "mygroup"
    when
    then
    	System.out.pringln("规则rule_activationgroup_2触发");
end

6. agenda-group属性

agenda-group属性为议程分组,属于另一种可控的规则执行方式。用户可以通过设置agenda-group来控制规则的执行,只有获取焦点的组中的规则才会被触发。
一般可以用在a,b规则与activation-group的区别是,通过焦点判定
第一步:创建规则文件/resources/rules/agendagroup.drl

package testagendagroup
/*
* 此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"
	agenda-group "myagendagroup_1" // agenda-group属性为议程分组,只有获得焦点的族中的规则才可以触发
	when
    then
		System.out.println("规则:rule_agendagroup_1触发了...");
end

rule "rule_agendagroup_2"
	agenda-group "myagendagroup_2"
    when
    then
end

rule "rule_agendagroup_3"
	agenda-group "myagendagroup_2"
    when
    then
end

rule "rule_agendagroup_4"
	agenda-group "myagendagroup_2"
    when
    then
end

第二步:在调用规则的session中设定焦点

session.getAgenda().getAgendaGroup("myagendagroup_2").setFocus();

7. auto-focus属性

auto-focus属性为自动获取焦点,取值类型为Boolean,默认值为false。一般结合agenda-group属性使用,当一个议程分组未获取焦点时,
可以设置auto-focus属性类控制。

package testagendagroup
/*
* 此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"
	agenda-group "myagendagroup_1" // agenda-group属性为议程分组,只有获得焦点的族中的规则才可以触发
	when
    then
		System.out.println("规则:rule_agendagroup_1触发了...");
end

rule "rule_agendagroup_2"
	auto-focus true // auto-focus属性用于指定当前所属组自动获取焦点,只要在一个组里面的其中一个规则设置该属性则整个组生效
	agenda-group "myagendagroup_2"
    when
    then
end

rule "rule_agendagroup_3"
	agenda-group "myagendagroup_2"
    when
    then
end

rule "rule_agendagroup_4"
	agenda-group "myagendagroup_2"
    when
    then
end

8. timer属性

timer属性可以通过定时器的方式指定规则执行的时间,使用方式有两种:

方式一:timer(int:<initial delay><repeat interval>?)
此种方式遵循java.util.Timer对象的使用方式,第一个参数表示几秒后执行,第二个参数表示每隔几秒执行一次,第二个参数为可选。
方式二:timer(cron:<cron expression>)
此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。

第一步:创建规则文件/resources/rules/timer.drl

package testtimer
import java.text.SimpleDateFormat
import java.util.Date
/**
* 此规则文件用于测试timer属性
*/
rule "rule_time_1"
	timer (3s 2s) // 当前timer属性用于指定规则触发的时间,当前这个表达式表示3秒后,每隔2s触发一次
    timer (cron:0/1 * * * * ?) // 第二种方式
	when
    then
    	System.out.println("规则:rule_timer_1触发了...");
end

第二步:

new Thread(() -> {
	// 启动规则引擎进行规则匹配,知道调用halt方法才结束规则引擎
	session.fireUntilHalt();
}).start();
Thread.sleep(10000);
// 结束规则引擎
kieSession.halt();
kieSession.dispose();

注意:代码和以前的有所不同,因为我们规则文件中使用到了timer进行时间执行,而安程序能够持续一段时间才能看到定时器触发的效果。

9. date-effective属性

date-effective属性用于指定规则的生效时间,即只有当前系统时间大于等于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy.用户也可以自定义日期格式。
第一步:编写规则文件/resources/rules/dateeffective.drl

package testdateeffective
/**
* 此规则文件用于测试date-effective属性
*/
rule "rule_dateeffective_1"
	date-effective "2020-10-01 10:00"
    when
    then
    	System.out.println("规则rule_dateeffective_2触发")
end

第二部:设置系统变量

System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm");
KieServices kieServices = KieServices.Factory.get();

10. date-expires属性

基本设置与date-effective类似,不做赘述。