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

rule "ruleName"attributeswhenLHSthenRHS
end

本篇就是针对规则体的attributes属性部分进行讲解。Drools中提供的属性如下表(部分属性):

属性名 说明
salience 指定规则执行优先级
dialect 指定规则使用的语言类型,取值为java和mvel
enabled 指定规则是否启用
date-effective 指定规则生效时间
date-expires 指定规则失效时间
activation-group 激活分组,具有相同分组名称的规则只能有一个规则触发
agenda-group 议程分组,只有获取焦点的组中的规则才有可能触发
timer 定时器,指定规则触发的时间
auto-focus 自动获取焦点,一般结合agenda-group一起使用
no-loop 防止死循环

1.enabled属性

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

rule "rule_student_age等于10岁用于删除"
enabled false
salience 10  //权重,保重该规则先执行when$s:Student(age == 10)thenretract($s);//删除内存中的对象System.out.println("规则rule_student_age等于10岁触发用于删除");
end

结果打印

说明
内存中的对象没有被删除,所以其他的规则被触发了。

2.dialect属性

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

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

3.salience属性

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

package rules;
dialect  "mvel"rule "rule_1"wheneval(true)thenSystem.out.println("规则rule_1触发");
endrule "rule_2"wheneval(true)thenSystem.out.println("规则rule_2触发");
endrule "rule_3"wheneval(true)thenSystem.out.println("规则rule_3触发");
end

测试代码

    @Testpublic void test5(){KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();int count = kieSession.fireAllRules();System.out.println("条数:"+count);}

结果打印

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

package rules;
dialect  "mvel"rule "rule_1"
salience 15wheneval(true)thenSystem.out.println("规则rule_1触发");
endrule "rule_2"
salience 20wheneval(true)thenSystem.out.println("规则rule_2触发");
endrule "rule_3"
salience 10wheneval(true)thenSystem.out.println("规则rule_3触发");
end

结果打印

通过控制台可以看到,规则文件执行的顺序是按照我们设置的salience值由大到小顺序执行的。
建议在编写规则时使用salience属性明确指定执行优先级。

4.no-loop属性

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

package rules;
dialect  "mvel"
import drools.entity.Studentrule "noloop"//no-loop truewhen$student:Student(age == 25)thenupdate($student);//注意此处执行update会导致当前规则重新被激活System.out.println("规则rule_noloop触发");
end

第二步:编写单元测试

    @Testpublic void test6(){KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();Student fact=new Student();fact.setAge(25);fact.setName("张三");System.out.println(fact);kieSession.insert(fact);int count = kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("noloop"));System.out.println("条数:"+count);System.out.println(fact);}

结果打印
打开注释前

打开注释后

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

5.activation-group属性

activation-group属性是指激活分组,取值为String类型。具有相同分组名称的规则只能有一个规则被触发。
第一步:编写规则文件/resources/rules/activationgroup.drl

package rules;
dialect  "mvel"
/*此规则文件用于测试activation-group属性
*/
rule "rule_activationgroup_1"activation-group "mygroup"whenthenSystem.out.println("规则rule_activationgroup_1触发");
end
rule "rule_activationgroup_2"activation-group "mygroup"whenthenSystem.out.println("规则rule_activationgroup_2触发");
end

第二步:编写单元测试

    @Testpublic void test7(){KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();int count = kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_activationgroup"));System.out.println("条数:"+count);kieSession.dispose();}

结果打印

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

6.agenda-group属性

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

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

package rules;
dialect  "mvel"/*此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"agenda-group "myagendagroup_aaa"whenthenSystem.out.println("规则rule_agendagroup_1触发");
endrule "rule_agendagroup_2"agenda-group "myagendagroup_aaa"whenthenSystem.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"agenda-group "myagendagroup_2"whenthenSystem.out.println("规则rule_agendagroup_3触发");
endrule "rule_agendagroup_4"agenda-group "myagendagroup_2"whenthenSystem.out.println("规则rule_agendagroup_4触发");
end

第二步:编写单元测试

    @Testpublic void test8() {KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();//设置焦点,对应agenda-group分组中的规则才可能被触发kieSession.getAgenda().getAgendaGroup("myagendagroup_2").setFocus();int count = kieSession.fireAllRules();System.out.println("条数:" + count);kieSession.dispose();}

结果打印

通过控制台可以看到,只有获取焦点的分组中的规则才会触发。与activation-group不同的是,activation-group定义的分组中只能够有一个规则可以被触发,而agenda-group分组中的多个规则都可以被触发。
疑问:对于指定分组的规则,的确只运行指定分组的规则,但是,对于没有设置指定分组的规则,只要符合过滤条件的也会执行。

7.auto-focus属性

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

第一步:修改/resources/rules/agendagroup.drl文件内容如下

package rules;
dialect  "mvel"/*此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"agenda-group "myagendagroup_1"auto-focus truewhenthenSystem.out.println("规则rule_agendagroup_1触发");
endrule "rule_agendagroup_2"agenda-group "myagendagroup_1"whenthenSystem.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"agenda-group "myagendagroup_2"whenthenSystem.out.println("规则rule_agendagroup_3触发");
endrule "rule_agendagroup_4"agenda-group "myagendagroup_2"whenthenSystem.out.println("规则rule_agendagroup_4触发");
end
``
第二步:编写单元测试
```java@Testpublic void test9() {KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();//设置焦点,对应agenda-group分组中的规则才可能被触发int count = kieSession.fireAllRules();System.out.println("条数:" + count);kieSession.dispose();}

结果打印:

通过控制台可以看到,设置auto-focus属性为true的规则都触发了。
疑问:经验证,发现只要agenda-group内有一个规则的auto-focus属性为true,该组内的所有规则都会执行。

8.timer属性

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

方式一:timer (int: ?)

此种方式遵循java.util.Timer对象的使用方式,第一个参数表示几秒后执行,第二个参数表示每隔几秒执行一次,第二个参数为可选。

方式二:timer(cron: )

此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。
第一步:创建规则文件/resources/rules/timer.drl

package rules;
dialect  "mvel"import java.text.SimpleDateFormat
import java.util.Date
/*此规则文件用于测试timer属性
*/
rule "rule_timer_1"timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次whenthenSystem.out.println("规则rule_timer_1触发,触发时间为:" +new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
endrule "rule_timer_2"timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次whenthenSystem.out.println("规则rule_timer_2触发,触发时间为:" +new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end

第二步:编写单元测试

    @Testpublic void test10() throws InterruptedException {KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();final KieSession kieSession = kieClasspathContainer.newKieSession();new Thread(new Runnable() {public void run() {//启动规则引擎进行规则匹配,直到调用halt方法才结束规则引擎kieSession.fireUntilHalt(new RuleNameStartsWithAgendaFilter("rule_timer"));}}).start();Thread.sleep(10000);//结束规则引擎kieSession.halt();kieSession.dispose();}

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

9.date-effective与date-expires属性

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

package rules;
dialect  "mvel"/*此规则文件用于测试date-effective属性
*/
rule "rule_dateeffective_1"
date-effective "2020-08-01 10:00"
date-expires "2020-10-01 10:00"whenthenSystem.out.println("规则rule_dateeffective_1触发");
end

第二步:编写单元测试

    @Testpublic void test11()  {System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();KieSession kieSession = kieClasspathContainer.newKieSession();int count = kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rule_dateeffective_1"));System.out.println("条数:" + count);kieSession.dispose();}

结果打印

Drools7.x 学习四-规则属性相关推荐

  1. Weka学习四(属性选择)

    在这一节我们看看属性选择.在数据挖掘的研究中,通常要通过距离来计算样本之间的距离,而样本距离是通过属性值来计算的.我们知道对于不同的属性,它们在样本空间的权重是不一样的,即它们与类别的关联度是不同的, ...

  2. oracle中的cursor属性有哪些,Oracle学习11:游标(cursor)--显式游标隐式游标、游标四个属性、循环遍历...

    1.概述 上文PLSQL学习中提到的知识,可以发现,基本都可以通过Java等语言实现,而为了实现程序的可移植性,实际开发工作中我们也是如此做的. 那么PLSQL的重点是什么呢?接下来我们来介绍游标cu ...

  3. Jsp学习总结(1)——JSP九大内置对象和四种属性范围解读

    一.四种属性范围 1.1.在JSP中提供了四种属性保存范围 page:在一个页面内保存属性,跳转之后无效 request:在一次服务请求范围内,服务器跳转后依然有效 session:-在一次会话范围内 ...

  4. 黑马Drools学习笔记(三)——Drools规则属性

    文章目录 规则属性 attributes 1 enabled属性 2 dialect属性 3 salience属性 4 no-loop属性 5 activation-group属性 6 agenda- ...

  5. JavaScript中的对象学习笔记(属性操作)

    本文是笔者学习JavaScript时做的笔记,大部分内容来自<JavaScript权威指南>,记录学习中的重点,并引入一些其他博文和与其他程序员讨论的内容,供本人日常翻阅.如有疑问,请留言 ...

  6. Linux学习(四)

    Linux学习(四) 用户身份与文件权限 用户身份与能力 linux系统中的管理员就是root,这是错误的,linux系统的管理员之所以是root,并非是他的名字叫root,而是因为该用户的身份号码即 ...

  7. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  8. PyTorch框架学习四——计算图与动态图机制

    PyTorch框架学习四--计算图与动态图机制 一.计算图 二.动态图与静态图 三.torch.autograd 1.torch.autograd.backward() 2.torch.autogra ...

  9. Docker学习四:Docker 网络

    前言 本次学习来自于datawhale组队学习: 教程地址为: https://github.com/datawhalechina/team-learning-program/tree/master/ ...

最新文章

  1. C#方法参数传递-同时使用ref和out关键字
  2. Activiti 6.x【6】StartEvent(上)
  3. c#链接操作mysql数据库代码_c#连接mysql数据库 代码
  4. 使用DML语句【weber出品必属精品】
  5. html css 极简模板,极简主义作品展示HTML模板
  6. pythonista3使用教程-pythonista3中文教程
  7. 字体rem通用基本设置
  8. mysql数据库导入导出_MySQL数据库导入导出详解
  9. 设置随机种子之后,网络训练结果仍然不同的解决方法(针对随机采样的数据集)torch设置随机种子,num_worker对数据采样的影响。
  10. Python机器学习 使用sklearn构建决策树复习
  11. python基础语法测评_3. Python基础语法
  12. bpsk调制matlab,matlab BPSK 调制与解调
  13. 《麦肯锡方法》阅读笔记2——探索分析问题的方法
  14. ctex linux安装_Deepin Linux 安装和搭建LaTex环境
  15. 计算机网络的资源子网,在计算机网络中,资源子网的功能是什么?
  16. week15——作业(字符串,完结撒花)
  17. Vue单页面应用性能优化实践
  18. macd指标在实战应用中效果如何,如何证明MACD指标详解能起到预警的作用
  19. “画仓鼠” 大赛,正式回归了!
  20. MSP-EXP430F5529LP_GPIO

热门文章

  1. 怎么去视频的水印?两分钟让你学会操作
  2. python 小学生教材全解_小学六年级教材全解
  3. 公众号内容拓展学习笔记(2021.3.25)
  4. MFC工具箱控件的一些用法
  5. P3480 [POI2009]KAM-Pebbles
  6. C语言中vu16什么意思,15.stm32 数据类型的定义(常用的U8,U16,U32到底代表什么)
  7. ENC28J60网络设备驱动分析
  8. SAP中成本核算时提示没有作业类型控制记录的实例
  9. css怎么设置table表格的边框为单线边框?(代码详解)
  10. 【ASP.net】--WebSite(网站) 和 WebApplication(Web应用程序)