首页 > 其他分享 >Drools业务规则管理系统25_规则属性

Drools业务规则管理系统25_规则属性

时间:2024-03-29 15:33:38浏览次数:23  
标签:Drools end 触发 System rule 25 规则 属性

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

 

rule "ruleName"
    attributes
    when
        LHS
    then
        RHS
end

 

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

 

 

一、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

二、dialect属性

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

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

三、salience属性

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

 可以通过创建规则文件salience.drl来测试salience属性,内容如下:

package test.salience

rule "rule_1"
    when
        eval(true)
    then
        System.out.println("规则rule_1触发");
end
    
rule "rule_2"
    when
        eval(true)
    then
        System.out.println("规则rule_2触发");
end

rule "rule_3"
    when
        eval(true)
    then
        System.out.println("规则rule_3触发");
end

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

package testsalience

rule "rule_1"
    salience 9
    when
        eval(true)
    then
        System.out.println("规则rule_1触发");
end

rule "rule_2"
    salience 10
    when
        eval(true)
    then
        System.out.println("规则rule_2触发");
end

rule "rule_3"
    salience 8
    when
        eval(true)
    then
        System.out.println("规则rule_3触发");
end

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

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

四、no-loop属性

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

package test.wql
import com.wql.model.Student
/*
    此规则文件用于测试no-loop属性
*/
rule "rule_noloop"
    when
        // no-loop true
        $student:Student(age == 25)
    then
        update($student);//注意此处执行update会导致当前规则重新被激活
        System.out.println("规则rule_noloop触发");
end

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

五、activation-group属性

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

  • 编写规则文件/resources/rules/activationgroup.drl
package testactivationgroup
/*
    此规则文件用于测试activation-group属性
*/

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

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

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

六、agenda-group属性

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

  • 创建规则文件/resources/rules/agendagroup.drl
package testagendagroup
/*
    此规则文件用于测试agenda-group属性
*/
rule "rule_agendagroup_1"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_1触发");
end

rule "rule_agendagroup_2"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_3触发");
end

rule "rule_agendagroup_4"
    agenda-group "myagendagroup_2"
    when
    then
        System.out.println("规则rule_agendagroup_4触发");
end
  • 测试
   @Test
    public void Test06(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

       //设置焦点,对应agenda-group分组中的规则才可能被触发
        kieSession.getAgenda().getAgendaGroup("myagendagroup_1").setFocus();

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

    }

 通过控制台可以看到,只有获取焦点的分组中的规则才会触发。与activation-group不同的是,activation-group定义的分组中只能够有一个规则可以被触发,而agenda-group分组中的多个规则都可以被触发。

七、auto-focus属性

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

 修改/resources/rules/agendagroup.drl文件内容如下

package testagendagroup


rule "rule_agendagroup_1"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_1触发");
end

rule "rule_agendagroup_2"
    agenda-group "myagendagroup_1"
    when
    then
        System.out.println("规则rule_agendagroup_2触发");
end
//========================================================
rule "rule_agendagroup_3"
    agenda-group "myagendagroup_2"
    auto-focus true //自动获取焦点
    when
    then
        System.out.println("规则rule_agendagroup_3触发");
end

rule "rule_agendagroup_4"
    agenda-group "myagendagroup_2"
    auto-focus true //自动获取焦点
    when
    then
        System.out.println("规则rule_agendagroup_4触发");
end
  • 编写单元测试
  @Test
    public void Test06(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.fireAllRules();
        kieSession.dispose();
    }

 通过控制台可以看到,设置auto-focus属性为true的规则都触发了。
 注意:同一个组,只要有个设置auto-focus true 其他的设置不设置都无所谓啦。都会起作用的。

八、timer属性

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

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

 timer(cron: )
  此种方式使用标准的unix cron表达式的使用方式来定义规则执行的时间。

  • 创建规则文件/resources/rules/timer.drl
package testtimer
import java.text.SimpleDateFormat
import java.util.Date
/*
    此规则文件用于测试timer属性
*/

rule "rule_timer_1"
    timer (5s 2s) //含义:5秒后触发,然后每隔2秒触发一次
    when
    then
        System.out.println("规则rule_timer_1触发,触发时间为:" +
                         new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end

rule "rule_timer_2"
    timer (cron:0/1 * * * * ?) //含义:每隔1秒触发一次
    when
    then
        System.out.println("规则rule_timer_2触发,触发时间为:" +
                         new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
  • 编写单元测试
 @Test
    public void Test06() 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();
            }
        }).start();

        Thread.sleep(10000);
        //结束规则引擎
        kieSession.halt();
        kieSession.dispose();
    }

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

九、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_1触发");
end
  • 编写单元测试
@Test
    public void Test06() throws InterruptedException {
        //设置日期格式
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.fireAllRules();
        kieSession.dispose();
    }

 注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。

十、date-expires属性

 date-expires属性用于指定规则的失效时间,即只有当前系统时间小于设置的时间或者日期规则才有可能触发。默认日期格式为:dd-MMM-yyyy。用户也可以自定义日期格式。

  • 编写规则文件/resource/rules/dateexpires.drl
package testdateexpires

/*
    此规则文件用于测试date-expires属性
*/

rule "rule_dateexpires_1"
    date-expires "2019-10-01 10:00"
    when
    then
        System.out.println("规则rule_dateexpires_1触发");
end
  • 编写单元测试
    @Test
    public void Test06() throws InterruptedException {
        //设置日期格式
        System.setProperty("drools.dateformat","yyyy-MM-dd HH:mm");
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();
        kieSession.fireAllRules();
        kieSession.dispose();
    }

 注意:上面的代码需要设置日期格式,否则我们在规则文件中写的日期格式和默认的日期格式不匹配程序会报错。

 

 

标签:Drools,end,触发,System,rule,25,规则,属性
From: https://www.cnblogs.com/ajing2018/p/18103952

相关文章

  • P6225
    P6225异或橙子题意一个长度为$n$的序列,每个数有一个初始值$a_i$,维护以下$q$个操作:单点修改给定区间$[l,r]$求其所有子区间的异或和对于所有数据,$0\lea_i\le10^9,1\len,q\le2\times10^5$分析01-枚举对于每一次询问,暴力枚举其所有子区间,时间复杂度$O(qn^2......
  • 10天【代码随想录算法训练营34期】 第五章 栈与队列part01(● 232.用栈实现队列 ● 22
    232.用栈实现队列classMyQueue:def__init__(self):self.queue=[]self.size=0defpush(self,x:int)->None:self.queue.append(x)self.size+=1defpop(self)->int:self.size-=1retur......
  • lanqiao106. 正则问题 (第八届蓝桥杯C++A组)或者 acwing 1225. 正则问题
    问题:知识补充:1. 正则表达式的计算①括号代表优先计算,②或符号代表二选一。比如给的例子:((xx|xxx)x|(x|xx))xx 2. 字符串的语法问题:string是字符串的类型,使用的时候也使像字符一样使用,加入定义stringstr,那么使用的时候要写成str[]思考:妈呀一开始我不会算正则表达......
  • pipeline拓扑裁剪规则
    1.1概述在一些usecase中,会有多个使用场景。根据不同的场景,需要构建不同的pipeline拓扑。例如,高通SATusecase有多个场景:EIS-Disable,EISv3等等对于这种情况有两种解决方案:1、第一个是为这类用例设计不同的pipeline,以适应其不同的usecase。然后,在场景变化时切换到相应的pipel......
  • L2-025 分而治之(与L2-013 红色警戒 差不多一模一样)
    原题链接题目:分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。输入输出格式:输入在第一行给出两个正整数N......
  • 代码随想录Day17 ● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和
     110.平衡二叉树 classSolution{public://返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1intgetHeight(TreeNode*node){if(node==NULL){return0;}intleftHeight=getHeight(node->left......
  • Drools业务规则管理系统25_Drools基础语法4
    一、规则文件构成在使用Drools时非常重要的一个工作就是编写规则文件,通常规则文件的后缀为.drl。drl是DroolsRuleLanguage的缩写。在规则文件中编写具体的规则内容。一套完整的规则文件内容构成如下:package其实就是一个逻辑层面的划分,不同于java里面的包名,说白......
  • redis自学(25)过期策略
    Redis内存回收Redsi之所以性能强,最主要的原因就是基于内存存储。然而但决断的redis其内存大小不宜过大,会影响持久化或者主从同步性。我们可以通过修改配置文件来设置redis的最大内存:  当内存使用达到上限时,就无法存储更多数据了过期策略在学习redis缓存的时候我们说过,可......
  • 3.25~3.28
    另:?咋写这玩意的时候突然耳鸣了几秒我不会要趋势了吧(我发现和5k聊题总会出点问题倒不是说听不懂他的思路而是出在一些奇奇怪怪的地方......
  • Drools业务规则管理系统25_Drools入门案例3
    一、业务场景说明业务场景:消费者在图书商城购买图书,下单后需要在支付页面显示订单优惠后的价格。具体优惠规则如下:二、开发实现1、导入核心依赖<dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artif......