Drools

Drools学习

官方文档

几篇参考的博客:

全局Global参数设置:https://www.cnblogs.com/wwjj4811/p/15294523.html

fireAllRules使用指定规则名:https://blog.csdn.net/u013115157/article/details/52487001

规则引擎高级语法:https://blog.csdn.net/qq_36305027/article/details/106562422?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0.essearch_pc_relevant&spm=1001.2101.3001.4242.1

pom依赖

包括Drools相关依赖、lombak依赖、junit单元测试依赖

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>


		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
			<version>7.23.0.Final</version>
		</dependency>

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

		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-decisiontables</artifactId>
			<version>7.23.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-templates</artifactId>
			<version>7.23.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.kie</groupId>
			<artifactId>kie-api</artifactId>
			<version>7.23.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<version>2.5.4</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
			<version>1.18.16</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.13.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

配置文件设置

在classpath下配置drools配置文件,文件的路径为resource/META-INF/kmodule.xml,该配置文件必须在这个目录下,放到其他地方无法生效

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <!--
        name:指定kbase的名称,可以任意,但是需要唯⼀
        packages:指定规则⽂件的⽬录,需要根据实际情况填写,否则⽆法加载到规则⽂件
        default:指定当前kbase是否为默认
    -->
    <kbase name="myKbase1" packages="rules" default="true">
        <!--
            name:指定ksession名称,可以任意,但是需要唯⼀
            default:指定当前session是否为默认
        -->
        <ksession name="ksession-rule" default="true"/>
    </kbase>
</kmodule>

配置文件参数配置

在这里插入图片描述

规则类定义

规则类其实就是一个普通的class类

import  com.drools.demo.entity;

import lombok.Data;

/**
 * @author groundless
 * @Date 2021/11/29 16:02
 * @Description person
 */
@Data
public class Person {

    private String name;

    private int age;
}
package com.drools.demo.entity;

import lombok.Data;

/**
 * @author groundless
 * @Date 2021/11/29 16:55
 * @Description RuleBack (后面用于global对象返回使用)
 */
@Data
public class RuleBack {

    private String desc;
}

规则文件

规则文件定义到resource/rule文件夹下

rules.drl

import com.drools.demo.entity.Person
import javax.management.Descriptor
import com.drools.demo.entity.RuleBack;
dialect  "mvel"

global RuleBack ruleBack;

rule "rules"
    when
        $person : Person(age >= 18 && age <= 60)
    then
        System.out.println("rules");
        ruleBack.setDesc("rules back");
        $person.setName("rules");
end

personRules.drl

import com.drools.demo.entity.Person;
import com.drools.demo.entity.RuleBack;


dialect  "mvel"

global RuleBack ruleBack;

rule "personRules"
    when
        $s : Person(name == '111')
    then
        System.out.println("personRules");
        $s.setName("personRules");
        ruleBack.setDesc("personRule back");
end

规则调用

public void test(Person person){
    // 获取规则引擎服务
    KieServices kieServices = KieServices.Factory.get();
    // 创建规则容器
    KieContainer container = kieServices.getKieClasspathContainer();
    // 获取规则session
    KieSession kieSession = container.newKieSession("all-rules");
    // 加载校验对象
    kieSession.insert(person);
    RuleBack ruleBack = new RuleBack();
    // 设置全局参数
    kieSession.setGlobal("ruleBack", ruleBack);
    // 执行规则校验
    int i = kieSession.fireAllRules(); // 所有的规则都进行匹配一遍
    //        int i = kieSession.fireAllRules(new RuleNameEqualsAgendaFilter("rules1")); // 匹配指定名称的规则
    //        int i = kieSession.fireAllRules(new RuleNameMatchesAgendaFilter("all-rules")); // 通过正则匹配满足要求的规则
    //        int i = kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rules")); // 匹配以指定名称开头的规则
    //        kieSession.fireAllRules(new RuleNameEndsWithAgendaFilter("rules")); // 匹配以指定名称结尾的规则
    // 关闭session
    kieSession.dispose(); 
}

Drools语法

规则文件构成

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

⼀套完整的规则⽂件内容构成如下:

  • package:包名,package对应的不⼀定是真正的⽬录,可以任意写com.abc,同⼀个包下的drl⽂ 件可以相互访问
  • import:⽤于导⼊类或者静态⽅法
  • global:全局变量
  • function:⾃定义函数
  • query:查询
  • rule end:规则体
规则语法结构

⼀个规则通常包括三个部分:属性部分(attribute) 、条件部分(LHS)和结果部分(RHS)

rule "ruleName" //rule关键字,表示规则开始,参数为规则的唯⼀名称
	attributes //规则属性,是rule与when之间的参数,为可选项
when //关键字,后⾯是规则的条件部分
	LHS //Left Hand Side,是规则的条件部分
then //后⾯跟规则的结果部分
	RHS //是规则的结果或⾏为
end //表示⼀个规则的结束
条件部分

LHS(Left Hand Side):是规则的条件部分的通⽤名称。它由零个或多个条件元素组成。如果LHS 为空,则它将被视为始终为true的条件元素。 (左⼿边)

LHS部分由⼀个或者多个条件组成,条件⼜称为pattern。

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

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

rule "rules"
    when
        $person : Person(age >= 18)
    then
        System.out.println("rules");
        ruleBack.setDesc("rules back");
        $person.setName("rules");
end

如果 LHS 部分为空的话,那么引擎会⾃动添加⼀个 eval(true)的条件,由于该条件总是返回 true,所 以 LHS 为空的规则总是返回 true

1.约束连接

在 LHS 当中,可以包含 0~n 个条件,多个pattern之间可以采⽤“&&” (and) 、 “||”(or)和“,”(and) 来实现,也可以不写,默认连接为and。

2.⽐较操作符

在 Drools当中共提供了⼗⼆种类型的⽐较操作符, 分别是: >、 >=、 <、 <=、 = =、 !=、 contains、 not contains、memberof、not memberof、matches、not matches;在这⼗⼆种类型的 ⽐较操作符当中,前六个是⽐较常⻅也是⽤的⽐较多的⽐较操作符

符号说明
>大于
<小于
>=大于等于
<=小于等于
==等于
!=不等于
contains检查⼀个Fact对象的某个属性值是否包含⼀个指 定的对象值
not contains检查⼀个Fact对象的某个属性值是否不包含⼀个 指定的对象值
memberOf判断⼀个Fact对象的某个属性是否在⼀个或多个 集合中
not memberOf判断⼀个Fact对象的某个属性是否不在⼀个或多 个集合中
matches判断⼀个Fact对象的属性是否与提供的标准的 Java正则表达式进⾏匹配
not matches判断⼀个Fact对象的属性是否不与提供的标准的 Java正则表达式进⾏匹配
结果部分

在 Drools 当中,在 RHS ⾥⾯,提供了⼀些对当前 Working Memory 实现快速操作的宏宏函数或对 象, ⽐如 insert/insertLogical、 update 和 retract 就可以实现对当前 Working Memory中的 Fact 对象进⾏新增、删除或者是修改

  1. insert
    函数insert的作⽤与我们在Java类当中调⽤StatefulKnowledgeSession对象的insert⽅法的作⽤相同, 都是⽤来将⼀个 Fact 对象插⼊到当前的 Working Memory 当中 需注意:⼀旦调⽤ insert 宏函数,那么 Drools 会重新与所有的规则再重新匹配⼀次, 对于没有设置 no-loop 属性为 true 的规则,如果条件满⾜,不管其之前是否执⾏过都会再执⾏⼀次,这个特性不仅 存在于 insert 宏函数上,后⾯介绍的 update、retract 宏函数同样具有该特性,所以在某些情况下因考 虑不周调⽤ insert、update 或 retract 容易发⽣死循环

    rule "rule5"
    when
    	eval(true); //默认成⽴
    then
        Person p=new Person();
        p.setName("张三");
        insert(cus);
        System.out.println("测试Drools提供的内置⽅法insert 触发...");
    end
    
  2. update

    update函数意义与其名称⼀样, ⽤来实现对当前Working Memory当中的 Fact进⾏更新,⽤来告诉当 前的 Working Memory 该 Fact 对象已经发⽣了变化。

    rule "rule5"
    when
    	$p:Person(name == "张三")
    then
        $p.setName("李四");
        pudate($p);
        System.out.println("测试Drools提供的内置⽅update 触发...");
    end
    
  3. retract
    retract⽤来将 Working Memory 当中某个 Fact 对象从 Working Memory 当中删除

    rule "rule5"
    when
    	$p:Person(name == "张三")
    then
        retract($p);
        System.out.println("测试Drools提供的内置⽅retract 触发...");
    end
    
属性部分
属性名说明
salience指定规则执⾏优先级
dialect指定规则使⽤的语⾔类型,取值为java和mvel
enabled指定规则是否启⽤
date-effective指定规则⽣效时间
date-expires指定规则失效时间
activation-group激活分组,具有相同分组名称的规则只能有⼀个 规则触发
agenda-group议程分组,只有获取焦点的组中的规则才有可能 触发
timer定时器,指定规则触发的时间
auto-focus⾃动获取焦点,⼀般结合agenda-group⼀起使 ⽤
no-loop防⽌死循环
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值