熟练使用Drools规则引擎

介绍
规则引擎全称为业务规则管理系统,英文名称为BRMS 就像是一个数据库 只不过规则引擎存储的都是业务的规则数据 我们可以在规则引擎上对每个规则进行配置 添加或者修改 常用的规则引擎就有drools 作用就是接收数据的输入后 然后对数据进行规则校验 最后符合规则的数据在做数据的输出

使用规则引擎的优点?

  1. 代码和业务规则进行分离 并且规则可以集中管理
  2. 在不重启服务的情况下对业务规则进行扩展和维护
  3. 可以动态的修改业务规则 实现快速响应需求的变更

什么样的场景适合使用规则引擎?
比较复杂的业务规则并且业务规则会频繁变动的系统适合使用规则引擎

入门案例

导入依赖

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.10.0.Final</version>
</dependency>

在项目中创建resources/META-INF/kmodule.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">

    <!--
        name:指定kbase名称 唯一
        packages:指定规则文件 根据创建的规则文件来写 否则检测不到
        default:当前kabse是否为默认
      -->
    <kbase name="kbase" packages="test" default="true">
        <!--
            name:指定ksession名称 唯一
            default:指定当前ksession是否为默认
        -->
        <ksession name="ksession-test" default="true"/>
    </kbase>

</kmodule>在这里插入代码片

创建实体类

@Data
public class OrderDTO {

    /**
     * 价格
     */
    private BigDecimal price;

    /**
     * 名称
     */
    private String name;



}

在项目resources/test/order.drl创建drl文件

在这里插入图片描述
编写第一条规则

package drosl.order;

import com.macro.mall.dto.OrderDTO;

// rule: 规则的唯一名称
// when:条件判断体
// then:规则执行体
// end:表示规则结束
rule "规则1、如果订单金额大于1000则触发此规则"
    when
        $order:OrderDTO(price > 1000)
    then
        System.out.println("规则1触发了,金额大于了1000元,当前的金额为 = " + $order.getPrice());
    end

创建测试类

    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        // 创建kie容器对象
        KieContainer kieContainer = kieServices.newKieClasspathContainer();
        // 从kie容器对象中获取会话对象
        KieSession session = kieContainer.newKieSession();
        // 创建Order对象
        OrderDTO dto = new OrderDTO();
        // 赋值测试数据
        dto.setPrice(new BigDecimal("20000"));
        // 将Order对象保存到工作内存当中
        session.insert(dto);
        // 激活规则 Drools会自动匹配规则 匹配成功则执行规则
        session.fireAllRules();

    }

执行结果
在这里插入图片描述

语法说明

package drosl.order;

import com.macro.mall.dto.OrderDTO;
import com.macro.mall.dto.CsDto;

// rule: 规则的唯一名称
// when:条件判断体
// then:规则执行体
// end:表示规则结束
rule "规则1、如果订单金额大于1000则触发此规则"
    when
        // $order:表示该对象的名称 可以为任意
        $order:OrderDTO(price > 1000)
        $cs:CsDto(name = "张三" && age > 18)
        // 也可以写多个条件 可以用and 或者 or 拼接 如果不写 默认为and
    then
        // $order.getPrice():因为上面该对象已经取名$order 所以就可以直接用$order 获取对象的值
        System.out.println("规则1触发了,金额大于了1000元,当前的金额为 = " + $order.getPrice());
    end

关键字解释

关键字描述
packagedrools文件名称,可以随意
import导入类或者静态方法 只有导入的类和静态方法 drools才可以使用
global全局变量
function自定义函数
query查询
rule end规则体

关键字描述
rule规则名称 可以随意。但是必须唯一 可以是英文也可以是汉字
attributes规则属性。是rule与when之间的参数 非必写
when所有的规则条件都在when下写
LHS是规则条件的通用名称 由一个或者多个条件组成 如果LHS为空 则它将被视为true
then所有的执行体都在then下写
RHS是执行体的通用名称
end表示规则结束

比较符解释

关键字描述
>大于
<小于
>=大于等于
<=小于等于
==等于
!=不等于
contains判断一个对象的某个属性值是否包含一个指定对象的值
not contains判断一个对象的某个属性值是否不包含一个指定的对象值
memberOf判断一个对象的某个属性是否在一个或多个集合中

内置方法说明

  • update 方法
rule "规则2、测试规则内置方法"
    when
        $order:OrderDTO(price > 1000)
    then
        System.out.println("规则2触发了,update方法前的金额为 = " + $order.getPrice());
        $order.setPrice(new BigDecimal("10"));
        update($order);
        System.out.println("规则2触发了,update方法后的金额为 = " + $order.getPrice());
    end

rule "规则3、测试规则内置方法"
    when
        $order:OrderDTO(price == 10)
    then
        System.out.println("规则3触发了,当前的金额为 = " + $order.getPrice());
    end
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        // 创建kie容器对象
        KieContainer kieContainer = kieServices.newKieClasspathContainer();
        // 从kie容器对象中获取会话对象
        KieSession session = kieContainer.newKieSession();
        // 创建Order对象
        OrderDTO dto = new OrderDTO();
        // 赋值测试数据
        dto.setPrice(new BigDecimal("20000"));
        // 将Order对象保存到工作内存当中
        session.insert(dto);
        System.out.println("规则执行前 对象的金额为 = "+ dto.getPrice());
        // 激活规则 Drools会自动匹配规则 匹配成功则执行规则
        session.fireAllRules();
        System.out.println("规则执行后 对象的金额为 = "+ dto.getPrice());

    }

在这里插入图片描述

从执行结果可以看出 update执行后将会对对象的属性修改。并且修改后 规则文件会重新执行。

  • insert 方法
rule "规则4、测试规则内置方法"
    when

    then
        OrderDTO dto = new OrderDTO();
        System.out.println("规则4触发了,insert方法前的金额为 = " + dto.getPrice());
        dto.setPrice(new BigDecimal("10"));
        insert(dto);
        System.out.println("规则4触发了,insert方法后的金额为 = " + dto.getPrice());
    end


rule "规则5、测试规则内置方法"
    when
        $order:OrderDTO(price == 10)
    then
        System.out.println("规则5触发了,当前的金额为 = " + $order.getPrice());
    end
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        // 创建kie容器对象
        KieContainer kieContainer = kieServices.newKieClasspathContainer();
        // 从kie容器对象中获取会话对象
        KieSession session = kieContainer.newKieSession();
        // 创建Order对象
        OrderDTO dto = new OrderDTO();
        // 将Order对象保存到工作内存当中
        session.insert(dto);
        System.out.println("规则执行前 对象的金额为 = "+ dto.getPrice());
        // 激活规则 Drools会自动匹配规则 匹配成功则执行规则
        session.fireAllRules();
        System.out.println("规则执行后 对象的金额为 = "+ dto.getPrice());

    }

在这里插入图片描述

从执行结果可以看出 对对象insert值后 规则文件也会重新匹配 但是和update不同的是 insert的值只限于工作内存当中

  • retract 方法
rule "规则6、测试规则内置方法"
    when
       $order:OrderDTO(price == 10000)
    then
        retract($order);
    end

基本属性

关键字描述
enabled指定当前的规则是否启用 默认为true
dialect选择当前规则的语言类型 比如是java/mvel 默认为java
salience指定执行的优先级 数值越高越先执行
no-loop作用是防止出现死循环 因为当通过修改对对象操作之后 规则就会重新校验 这样当前的这个规则可能就会被在次的激活 从而导致循环执行 默认为false
activation-group作用是创建规则分组 在相同的组内的规则只能有一个被触发 取值为String类型
agenda-group可以设置焦点的分组 比如我设置了两个组 我只想用组1的规则 那么我就需要在java代码中设置焦点设置 设置的组才可以执行校验 没有的则不会执行
auto-focus作用是自己给自己设置焦点 只能在agenda-group 分组下使用 当java代码没有设置焦点的时候 该分组如果想要被执行 那么就可以自己给自己设置焦点 默认为false
timer可以指定几秒后执行 或者几秒后执行然后每隔几秒在执行
date-effectice作用是指定规则生效的时间 当系统的时间大于设置的时间才会执行 时间的格式为yyyy-MM-dd HH:mm:ss
date-expires作用是指定规则的失效时间 当系统的时间小于设置的时间才会出发 时间的格式为yyyy-MM-dd HH:mm:ss

高级语法

  1. global:设置全局变量
global java.lang.Integer count

global java.util.List list

rule "规则8、测试高级语法"
    when

    then
        System.out.println("规则8触发了,全局变量的值为 = " + count);
        System.out.println("规则8触发了,全局变量list的值为 = " + list);
    end
// 设置全局变量
session.setGlobal("count",3000);
List<String> list = new ArrayList<>();
list.add("hahhah");
list.add("heehhhe");
session.setGlobal("list",list);

在这里插入图片描述

  1. query 查询符合条件的对象
query "query01"
    $order:OrderDTO(price == 100000)
end

query "query02"(Long prc)
    $order:OrderDTO(price == prc)
end
 // 创建Order对象
 OrderDTO dto = new OrderDTO();
 // 赋值测试数据
 dto.setPrice(new BigDecimal("10000"));
 OrderDTO dto2 = new OrderDTO();
 dto2.setPrice(new BigDecimal("100000"));
 // 将Order对象保存到工作内存当中
 session.insert(dto);
 session.insert(dto2);
 QueryResults results = session.getQueryResults("query01");
 QueryResults results2 = session.getQueryResults("query02",10000);
 System.out.println("results符合条件的个数 = "+results.size());
 System.out.println("results2符合条件的个数 = "+results2.size());

在这里插入图片描述
3. function 定义函数

function String sys(String name){
    return "自定义函数" + name;
}

rule "规则9、测试规则内置方法"
    when

    then
        String name = sys("规则9");
        System.out.println("规则9触发了 = " + name);
    end

在这里插入图片描述

  1. in / not in关键字
$order:OrderDTO(name in ("张三","李四","王武"))
$order:OrderDTO(name not in ("校长","老师","学生"))
  1. eval关键字 (放在LHS执行 如果是写true 则该规则执行 否则false 则不执行)
when
  eval(false)
  eval(true)
  eval(1 == 1)
then
  1. exists关键字 (判断工作内存中 指定的对象是否存在如果存在则返回true 规则执行 否则返回false 规则不执行)
exists OrderDTO()
exists OrderDTO(price == 100 && name != null)
  1. extends关键字 (作用是继承 如果父规则触发了那么子规则也会触发 所以两个规则必须同时满足才可以)
rule "规则10、测试高级语法"
    when
        exists OrderDTO(price == 100)
    then

    end

rule "规则11、测试高级语法" extends "规则10、测试高级语法"
    when
        // 需要注意的是 此时的规则条件是两个 一个是父规则的条件 + 子规则的条件
        exists OrderDTO(name != null)
    then
        System.out.println("规则10执行了");
    end
  1. halt方法 (当某一个规则调用了该方法 那么该规则下面所有的规则都不会执行 不管是否条件满足)
rule "规则12、测试高级语法"
    when

    then
        // 此时的12规则调用了halt 那么12下面的所有规则都不会在执行 不管规则是否满足
        drools.halt();
    end

ps:一只小菜鸟 一直在学习 从未敢停止

第一章 规则引擎初步了解 5 1 为什么会有规则引擎? 5 2 什么是规则引擎? 5 3 为何要使用规则引擎? 6 3.1 声明式编程 6 3.2逻辑与数据分离 6 3.3 速度及可测量性 6 3.4 知识集中化 6 3.5 工具集成 6 3.6 解释机制 6 3.7易懂的规则 7 4 何时应当使用规则引擎? 7 5 如何使用规则引擎? 7 6 何时不要使用规则引擎 ? 8 7 规则引擎的架构和推理 8 8规则引擎的算法 10 9 Java规则引擎商业产品 10 10 Dools介绍 11 第二章. Drools 规则引擎 11 2.1. 概述 11 2.2. 编制 13 2.3. RuleBase 18 2.4. WorkingMemory 和有状态/无状态Sessions 22 2.5. StatefulSession 28 2.6. StatelessSession 29 2.7. Agenda 31 2.8. Truth Maintenance with Logical Objects 34 2.9. 事件模型(Event Model) 37 2.10. 顺序模式 41 第三章. 安装和设置(Core 与IDE) 42 3.1. 安装和使用 42 3.1.1. 依赖库 42 3.1.2. 运行时(Runtime) 43 3.1.3. 安装IDE (规则工作台) 43 3.2. 从源码进行安装 54 3.3. 源码Checkout 54 3.4. 构建 59 3.4.1. 构建源码 59 3.4.2. 构建使用手册 61 3.5. Eclipse 65 3.5.1. 产生Eclipse项目 65 3.5.2. 导入Eclipse项目 66 3.5.3. 导出IDE插件 71 3.5.4. 构建更新站点 76 第四章. 决策表 78 4.1. 在电子表格中的决策表 78 4.1.1. 何时使用决策表 78 4.1.2. 概述 79 4.1.3. 决策表如何工作 81 4.1.4. 关键字和语法 83 4.1.5. 基于决策表建立并集成电子表格 87 4.1.6. 在决策表中管理业务规则 88 第五章. 规则工作台 (IDE) 89 5.1. Introduction 89 5.1.1. 特性概要 90 5.1.2. 建立规则项目 90 5.1.3. 新建规则向导 92 5.1.4. 规则编辑器 94 5.1.5. 视图 95 5.1.6. 领域规范语言DSL 98 5.1.7. The Rete视图 100 5.1.8. 大容量DRL文件 101 5.1.9. 调试规则 102 第六章. 规则语言 103 6.1. 概述 103 6.1.1. 规则文件 103 6.1.2. 规则的构成 104 6.1.3. 保留字 104 6.2. Comments注释 106 6.2.1. 单行注释 106 6.2.2. 多行注释 106 6.3. Package 107 6.3.1. import 108 6.3.2. expander 108 6.3.3. global全局变量 108 6.4. Function 110 6.5. Rule 111 6.5.1. Rule 属性 112 6.5.2. LHS (when) 条件元素 115 6.5.3. The Right Hand Side (then) 140 6.5.4. 对自动封箱/拆箱以及元数据类型的注解 141 6.6. Query 141 6.7. Domain Specific Languages 领域特定语言 142 6.7.1. 何时使用DSL 142 6.7.2. 编辑与管理DSL 143 6.7.3. 在规则中使用DSL 144 6.7.4. 增加对fact的约束 145 6.7.5. DSL如何工作 146 6.7.6. 从头开始建立DSL 146 6.8. 规则流 147 6.8.1. 设置规则所属的规则流组 148 6.8.2. 简单的规则流 148 6.8.3. 如何建立规则流 148 6.8.4. 在你的应用程序中使用规则流 153 6.9. XML规则语言 153 6.9.1. 何时使用XML 153 6.9.2. XML 格式 154 6.9.3. 遗留的Drools 2.x XML 规则格式 159 6.9.4. Automatic transforming between formats (XML and DRL) 159 第七章:部署和测试 160 7.1. 部署选项 160 7.1.1. 使用RuleAgent部署 160 7.1.2. 使用drl源码部署 161 7.1.3. 在你的classpath中部署规则 161 7.1.4. 可部署的对象RuleBase, Package等等. 161 7.1.5. 部署模式 163 7.1.6. Web Services 166 7.1.7. 未来的构想 166 7.2. 测试 166 7.2.1. 测试框架 166 7.2.2. FIT for Rules – 一种规则测试框架 166 第八章. BRMS (业务规则管理系统) 168 8.1. 简介 168 8.1.1. 什么是BRMS? 169 8.1.2. 特性概要 170 8.2. 管理指南 170 8.2.1. 安装 171 8.2.2. 数据库配置 172 8.2.3. 安全性 173 8.2.4. 数据管理 176 8.3. 体系结构 178 8.3.1. 从源码构建 179 8.3.2. 可重用组件 180 8.3.3. 版本和存储库 180 8.3.4. 贡献 181 8.4. 快速使用指南 181 8.4.1. 快速使用指南 181 8.4.2. BRMS 概念 183 8.4.3. The business user perspective 197 8.4.4. 部署: 将规则与你的应用集成 197 8.5. 例子与教程 200 8.5.1. 保险经济折扣 200 第九章. Java规则引擎API 202 9.1 简介 202 9.2 java规则引擎API体系结构 202 9.3 规则管理API 202 9.4 运行时API 203 9.5 java规则引擎API的安全问题 204 9.6 异常与日志 205 9.7 JSR小结 205 9.8 Dools API 参考 205 9.8.1 简介 205 9.8.2. 如何使用 205 9.8.3. 参考书目 209
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TianYuuuuuuuuuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值