首页 > 其他分享 >Drools业务规则管理系统25_Drools基础语法4

Drools业务规则管理系统25_Drools基础语法4

时间:2024-03-28 17:24:08浏览次数:13  
标签:Drools 20 管理系统 age rule 25 student 规则 10

一、规则文件构成

 在使用Drools时非常重要的一个工作就是编写规则文件,通常规则文件的后缀为.drl

 drl是Drools Rule Language的缩写。在规则文件中编写具体的规则内容。

 一套完整的规则文件内容构成如下:

  

  • package 其实就是一个逻辑层面的划分,不同于java里面的包名,说白了就是一个区域标识;
  • import 就是导入类,和java里面一样玩法 使用$符号引用

 Drools支持的规则文件,除了drl形式,还有Excel文件类型的。

二、规则体语法结构

 规则体是规则文件内容中的重要组成部分,是进行业务规则判断、处理业务结果的部分。

 规则体语法结构如下:

rule "ruleName"
    attributes
    when
        LHS 
    then
        RHS
end
  • rule:关键字,表示规则开始,参数为规则的唯一名称。
  • attributes:规则属性,是rule与when之间的参数,为可选项。
  • when:关键字,后面跟规则的条件部分。
  • LHS(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素。 (左手边)
  • then:关键字,后面跟规则的结果部分。
  • RHS(Right Hand Side):是规则的后果或行动部分的通用名称。 (右手边)
  • end:关键字,表示一个规则结束。

三、注释

 在drl形式的规则文件中使用注释和Java类中使用注释一致,分为单行注释和多行注释。

 单行注释用"//“进行标记,多行注释以”/“开始,以”/"结束。如下示例:

//规则rule1的注释,这是一个单行注释
rule "rule1"
    when
    then
        System.out.println("rule1触发");
end

/*
规则rule2的注释,
这是一个多行注释
*/
rule "rule2"
    when
    then
        System.out.println("rule2触发");
end

四、Pattern模式匹配

 前面我们已经知道了Drools中的匹配器可以将Rule Base中的所有规则与Working Memory中的Fact对象进行模式匹配,那么我们就需要在规则体的LHS部分定义规则并进行模式匹配。LHS部分由一个或者多个条件组成,条件又称为pattern。

 pattern的语法结构为:绑定变量名:Object(Field约束)

 其中绑定变量名可以省略,通常绑定变量名的命名一般建议以$开始。如果定义了绑定变量名,就可以在规则体的RHS部分使用此绑定变量名来操作相应的Fact对象。Field约束部分是需要返回true或者false的0个或多个表达式。

 例如我们的入门案例中:

//规则二:所购图书总价在100到200元的优惠20元
rule "book_discount_2"
    when
        //Order为类型约束,originalPrice为属性约束
        $order:Order(originalPrice < 200 && originalPrice >= 100)
    then
        $order.setRealPrice($order.getOriginalPrice() - 20);
        System.out.println("成功匹配到规则二:所购图书总价在100到200元的优惠20元");
end

 通过上面的例子我们可以知道,匹配的条件为:

  • 1、工作内存中必须存在Order这种类型的Fact对象-----类型约束
  • 2、Fact对象的originalPrice属性值必须小于200------属性约束
  • 3、Fact对象的originalPrice属性值必须大于等于100------属性约束

 以上条件必须同时满足当前规则才有可能被激活。

 绑定变量既可以用在对象上,也可以用在对象的属性上。例如上面的例子可以改为:

//规则二:所购图书总价在100到200元的优惠20元
rule "book_discount_2"
    when
        $order:Order($op:originalPrice < 200 && originalPrice >= 100)
    then
        System.out.println("$op=" + $op);
        $order.setRealPrice($order.getOriginalPrice() - 20);
        System.out.println("成功匹配到规则二:所购图书总价在100到200元的优惠20元");
end

 LHS部分还可以定义多个pattern,多个pattern之间可以使用and或者or进行连接,也可以不写,默认连接为and。

//规则二:所购图书总价在100到200元的优惠20元
rule "book_discount_2"
    when
        $order:Order($op:originalPrice < 200 && originalPrice >= 100) and
        $customer:Customer(age > 20 && gender=='male')
    then
        System.out.println("$op=" + $op);
        $order.setRealPrice($order.getOriginalPrice() - 20);
        System.out.println("成功匹配到规则二:所购图书总价在100到200元的优惠20元");
end

五、比较操作符

 Drools提供的比较操作符,如下表:

  

 前6个比较操作符和Java中的完全相同,下面我们重点学习后6个比较操作符。

  • contains | not contains语法结构
    • Object(Field[Collection/Array] contains value)
    • Object(Field[Collection/Array] not contains value)
  • memberOf | not memberOf语法结构
    • Object(field memberOf value[Collection/Array])
    • Object(field not memberOf value[Collection/Array])
  • matches | not matches语法结构
    • Object(field matches “正则表达式”)
    • Object(field not matches “正则表达式”)

 contain是前面包含后面,memberOf是后面包含前面

 演示比较操作符:

  • 创建实体类:
package com.wql.model;
import lombok.Data;
import java.util.List;

/**
 * @author wql
 * @date 2021/12/12 21:44
 */
@Data
public class ComparisonOperatorEntity {

    private String names;
    private List<String> list;
}
  • 创建规则
package comparisonOperator
import com.wql.model.ComparisonOperatorEntity
/*
 当前规则文件用于测试Drools提供的比较操作符
*/

//测试比较操作符contains
rule "rule_comparison_contains"
    when
        ComparisonOperatorEntity(names contains "张三")
        ComparisonOperatorEntity(list contains names)
    then
        System.out.println("规则rule_comparison_contains触发");
end

//测试比较操作符not contains
rule "rule_comparison_notContains"
    when
        ComparisonOperatorEntity(names not contains "张三")
        ComparisonOperatorEntity(list not contains names)
    then
        System.out.println("规则rule_comparison_notContains触发");
end

//测试比较操作符memberOf
rule "rule_comparison_memberOf"
    when
        ComparisonOperatorEntity(names memberOf list)
    then
        System.out.println("规则rule_comparison_memberOf触发");
end

//测试比较操作符not memberOf
rule "rule_comparison_notMemberOf"
    when
        ComparisonOperatorEntity(names not memberOf list)
    then
        System.out.println("规则rule_comparison_notMemberOf触发");
end

//测试比较操作符matches
rule "rule_comparison_matches"
    when
        ComparisonOperatorEntity(names matches "张.*")
    then
        System.out.println("规则rule_comparison_matches触发");
end

//测试比较操作符not matches
rule "rule_comparison_notMatches"
    when
        ComparisonOperatorEntity(names not matches "张.*")
    then
        System.out.println("规则rule_comparison_notMatches触发");
end
  • 测试
 //测试比较操作符
    @Test
    public void test3(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        ComparisonOperatorEntity comparisonOperatorEntity = new ComparisonOperatorEntity();
        comparisonOperatorEntity.setNames("张三");
        List<String> list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        comparisonOperatorEntity.setList(list);

        //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则
        kieSession.insert(comparisonOperatorEntity);

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

六、执行指定规则

 通过前面的案例可以看到,我们在调用规则代码时,满足条件的规则都会被执行。那么如果我们只想执行其中的某个规则如何实现呢?

 Drools给我们提供的方式是通过规则过滤器来实现执行指定规则。对于规则文件不用做任何修改,只需要修改Java代码即可,如下:

KieServices kieServices = KieServices.Factory.get();
KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieClasspathContainer.newKieSession();

ComparisonOperatorEntity comparisonOperatorEntity = new ComparisonOperatorEntity();
comparisonOperatorEntity.setNames("张三");
List<String> list = new ArrayList<String>();
list.add("张三");
list.add("李四");
comparisonOperatorEntity.setList(list);
kieSession.insert(comparisonOperatorEntity);

//通过规则过滤器实现只执行指定规则
kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rule_comparison_memberOf"));

kieSession.dispose();

七、关键字

 Drools的关键字分为:

  • 硬关键字(Hard keywords)
  • 软关键字(Soft keywords)

 硬关键字是我们在规则文件中定义包名或者规则名时明确不能使用的,否则程序会报错。软关键字虽然可以使用,但是不建议使用;
 硬关键字包括:true false null

 软关键字包括:lock-on-active date-effective date-expires no-loop auto-focus activation-group agenda-group ruleflow-group entry-point duration package import dialect salience enabled attributes rule extend when then template query declare function global eval not in or and exists forall accumulate collect from action reverse result end over init

比如:
rule true //不可以
rule “true” //可以

八、Drools内置方法

 规则文件的RHS部分的主要作用是通过插入,删除或修改工作内存中的Fact数据,来达到控制规则引擎执行的目的。Drools提供了一些方法可以用来操作工作内存中的数据,操作完成后规则引擎会重新进行相关规则的匹配,原来没有匹配成功的规则在我们修改数据完成后有可能就会匹配成功了。

 1、update方法

  update方法的作用是更新工作内存中的数据,并让相关的规则重新匹配。 (要避免死循环)

  • 编写student.drl
package student
import com.wql.model.Student

/*
 当前规则文件用于测试Drools提供的内置方法
*/

rule "rule_student_age小于10岁"
    when
        $s:Student(age < 10)
    then
        $s.setAge(15);
        update($s);//更新数据,导致相关的规则会重新匹配
        System.out.println("规则rule_student_age小于10岁触发");
end

rule "rule_student_age小于20岁同时大于10岁"
    when
        $s:Student(age < 20 && age > 10)
    then
        $s.setAge(25);
        update($s);//更新数据,导致相关的规则会重新匹配
        System.out.println("规则rule_student_age小于20岁同时大于10岁触发");
end

rule "rule_student_age大于20岁"
    when
        $s:Student(age > 20)
    then
        System.out.println("规则rule_student_age大于20岁触发");
end
  • 测试
@Test
    public void Test04() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Student student = new Student();
        student.setAge(5);

       //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则
        kieSession.insert(student);

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

  

   通过控制台的输出可以看到规则文件中定义的三个规则都触发了。
  在更新数据时需要注意防止发生死循环。

 2、insert方法

  insert方法的作用是向工作内存中插入数据,并让相关的规则重新匹配。

  • 修改student.drl文件内容如下
package student
import com.wql.model.Student

/*
 当前规则文件用于测试Drools提供的内置方法
*/

rule "rule_student_age等于10岁"
    when
        $s:Student(age == 10)
    then
        Student student = new Student();
        student.setAge(5);
        insert(student);//插入数据,导致相关的规则会重新匹配
        System.out.println("规则rule_student_age等于10岁触发");
end

rule "rule_student_age小于10岁"
    when
        $s:Student(age < 10)
    then
        $s.setAge(15);
        update($s);
        System.out.println("规则rule_student_age小于10岁触发");
end

rule "rule_student_age小于20岁同时大于10岁"
    when
        $s:Student(age < 20 && age > 10)
    then
        $s.setAge(25);
        update($s);
        System.out.println("规则rule_student_age小于20岁同时大于10岁触发");
end

rule "rule_student_age大于20岁"
    when
        $s:Student(age > 20)
    then
        System.out.println("规则rule_student_age大于20岁触发");
end
  • 编写单元测试
@Test
    public void Test05() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Student student = new Student();
        student.setAge(10);

        //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则
        kieSession.insert(student);

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

  

  通过控制台输出可以发现,四个规则都触发了,这是因为首先进行规则匹配时只有第一个规则可以匹配成功,但是在第一个规则中向工作内存中插入了一个数据导致重新进行规则匹配,此时第二个规则可以匹配成功。在第二个规则中进行了数据修改导致第三个规则也可以匹配成功,以此类推最终四个规则都匹配成功并执行了。

 3、retract方法

  retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。

  • 修改student.drl文件内容如下:
package student
import com.wql.model.Student

/*
 当前规则文件用于测试Drools提供的内置方法
*/

rule "rule_student_age等于10岁时删除数据"
    /*
    salience:设置当前规则的执行优先级,数值越大越优先执行,默认值为0.
    因为当前规则的匹配条件和下面规则的匹配条件相同,为了保证先执行当前规则,需要设置优先级
    */
    salience 100 
    when
        $s:Student(age == 10)
    then
        retract($s);//retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。
        System.out.println("规则rule_student_age等于10岁时删除数据触发");
end

rule "rule_student_age等于10岁"
    when
        $s:Student(age == 10)
    then
        Student student = new Student();
        student.setAge(5);
        insert(student);
        System.out.println("规则rule_student_age等于10岁触发");
end

rule "rule_student_age小于10岁"
    when
        $s:Student(age < 10)
    then
        $s.setAge(15);
        update($s);
        System.out.println("规则rule_student_age小于10岁触发");
end

rule "rule_student_age小于20岁同时大于10岁"
    when
        $s:Student(age < 20 && age > 10)
    then
        $s.setAge(25);
        update($s);
        System.out.println("规则rule_student_age小于20岁同时大于10岁触发");
end

rule "rule_student_age大于20岁"
    when
        $s:Student(age > 20)
    then
        System.out.println("规则rule_student_age大于20岁触发");
end
  • 编写单元测试
   KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Student student = new Student();
        student.setAge(10);

       //将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配,如果规则匹配成功则执行规则
        kieSession.insert(student);

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

  通过控制台输出可以发现,只有第一个规则触发了,因为在第一个规则中将工作内存中的数据删除了导致第二个规则并没有匹配成功。

 

 

标签:Drools,20,管理系统,age,rule,25,student,规则,10
From: https://www.cnblogs.com/ajing2018/p/18102181

相关文章

  • 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......
  • IT运维综合管理系统:提升效率、降低成本、保障安全
       随着信息技术的快速发展,企业对IT运维的需求也越来越高。IT运维综合管理系统作为一种集成化的解决方案,可以帮助企业提升运维效率、降低成本、保障信息安全。本文将从以下几个方面介绍IT运维综合管理系统的功能和优势。一、统一管理与监控   IT运维综合管理系统......
  • Drools业务规则管理系统25_规则引擎概述2
    一、什么是规则引擎规则引擎,全称为业务规则管理系统,英文名为BRMS(即BusinessRuleManagementSystem)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。需要注意的是规则引擎并......
  • [转帖]PCIe7.0宣布即将2025推出
    https://zhuanlan.zhihu.com/p/532935941 jiu导言在2022年的PCI-SIG的开发者大会上,PCI-SIG总裁庆祝了PCI-SIG成立30周年并宣布PCIe技术的下一代技术展望,并且计划在2025年向成员发布PCIe7.0标准。而在未来3年中即将推出的PCIe7.0再次提供速度提升(相比较PCIe6.0翻倍,X16双......
  • springboot/ssm城乡居民基本医疗信息管理系统Java医院挂号问诊系统web
    springboot/ssm城乡居民基本医疗信息管理系统Java医院挂号问诊系统web基于springboot(可改ssm)+vue项目开发语言:Java框架:springboot/可改ssm+vueJDK版本:JDK1.8(或11)服务器:tomcat数据库:mysql5.7(或8.0)数据库工具:Navicat/sqlyog开发软件:eclipse//idea依赖管理包:Mave......
  • 【附源码】django计算机毕业设计web的学生作业管理系统(源码+mysql+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:在当今信息化、数字化的教育环境中,学生作业管理已成为教学过程中不可或缺的一部分。传统的作业管理方式,如纸质作业本、电子邮件提交等,存在着效率低下、资源......
  • 【附源码】django计算机毕业设计病房管理系统设计与实现(源码+mysql+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:在现代医疗体系中,病房管理是医院运营的重要组成部分。随着科技的不断进步和信息化水平的提高,传统的手工或半自动化的病房管理模式已经无法满足现代医疗服务......
  • Centos7.5+k8s 1.25.0 部署手册
    目录Centos7.5+k8s1.25.0部署手册一、系统准备升级内核!!!1.环境信息(采用2个master节点+3个node节点),操作系统均为Centos7.52./etc/hosts文件修改3.关闭swap4.关闭防火墙5.关闭selinux6.更改yum源为阿里云7.配置所需依赖8.配置免密登录(master上执行,可省)9.配置主机名10.配......