Springboot整合规则引擎

Springboot整合Drools 规则引擎

1.添加maven 依赖坐标,并创建springboot项目

<!-- drools规则引擎 -->
<dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.6.0.Final</version>
</dependency><dependency><groupId>org.kie</groupId><artifactId>kie-api</artifactId><version>7.6.0.Final</version>
</dependency>
<dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId><version>7.6.0.Final</version>
</dependency><dependency><groupId>org.drools</groupId><artifactId>drools-decisiontables</artifactId><version>7.6.0.Final</version>
</dependency>
<dependency><groupId>org.drools</groupId><artifactId>drools-templates</artifactId><version>7.6.0.Final</version>
</dependency>

2.建立相应代码结构

1,创建实体类

@Data
public class Person {private String names;private List<String> list;}

3.在resources文件夹下创建META-INF 文件夹 和rules规则文件夹

META-INF下文件内容

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

Rules文件内容

package people;
import com.drools.demo.domain.Person
import com.drools.demo.service.DemoService
dialect "java"  #指定java语言
global DemoService demoService #设置全局变量
/*** 当前规则用于测试drools提供的操作运算符activation-group 同组只能又一个执行salience执行等级 salience 4 数值越大等级越高*/// 测试比较操作符contains #规则名称 全局唯一
rule "rule_comparison_contains"whenPerson(names contains "王小白")thendemoService.test();end// 测试比较操作符contains
rule "rule_comparison_not_contains"whenPerson(names not contains "王小白") andPerson(list not contains names)thenSystem.out.println("规则:rule_comparison_not_contains触发了...");
end// 测试比较操作符memberOf
rule "rule_comparison_memberOf"whenPerson(names memberOf list)thenSystem.out.println("规则:rule_comparison_memberOf触发了...");end// 测试比较操作符not memberOf
rule "rule_comparison_not_memberOf"whenPerson(names not memberOf list)thenSystem.out.println("规则:rule_comparison_not_memberOf触发了...");
end// 测试比较操作符matches
rule "rule_comparison_matches"whenPerson(names matches "王.*") // 正则表达式thenSystem.out.println("规则:rule_comparison_matches触发了...");
end// 测试比较操作符not matches
rule "rule_comparison_not_matches"whenPerson(names not matches "王.*") // 正则表达式thenSystem.out.println("规则:rule_comparison_not_matches触发了...");end

4.代码测试

@RestController
public class TestDemoController {@Resourceprivate DemoService demoService;@GetMapping("one")public void test(){KieServices kieServices = KieServices.Factory.get();// 获取Kie容器对象(默认容器对象KieContainer kieContainer = kieServices.newKieClasspathContainer();// 从Kie容器对象中获取会话对象(默认session对象KieSession kieSession = kieContainer.newKieSession();kieSession.setGlobal("demoService",demoService);Person fact = new Person();String names = "王小白";fact.setNames(names);List<String> list = new ArrayList<String>();list.add("小黑");list.add("王小白");list.add(names);fact.setList(list);// 将order对象插入工作内存kieSession.insert(fact);// 匹配对象// 激活规则,由drools框架自动进行规则匹配。若匹配成功,则执行kieSession.fireAllRules();// 关闭会话kieSession.dispose();}
}

Drools基础语法

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个或多个表达式。

//规则1:100元以下, 不加分
rule “score_1”
when
//⼯作内存中必须存在Order这种类型的Fact对象-----类型约束
//Fact对象的amout属性值必须⼩于等于100------属性约束
$s : Order(amout <= 100)
then
$s.setScore(0);
System.out.println("成功匹配到规则1:100元以下, 不加分 ");
end

如果 LHS 部分为空的话,那么引擎会⾃动添加⼀个 eval(true)的条件,由于该条件总是返回 true,所 以 LHS 为空的规则总是返回 true
1.约束连接
在 LHS 当中,可以包含 0~n 个条件,多个pattern之间可以采⽤“&&” (and) 、 “||”(or)和“,”(and) 来实现,也可以不写,默认连接为and
//规则2:100元-500元 加100分
rule “score_2”
when
$s : Order(amout > 100 && amout <= 500)
then
$s.setScore(100);
System.out.println("成功匹配到规则2:100元-500元 加100分 ");
end

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

示例:

第⼀步:创建实体类,⽤于测试⽐较操作符

package com.demo.entity; 
import java.util.List; 
public class Customer { 
//客户姓名 
private String name; 
private List<Order> orderList;//订单集合 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
public List<Order> getOrderList() { 
return orderList; 
} 
public void setOrderList(List<Order> orderList) { 
this.orderList = orderList; 
} 
}

第⼆步:在/resources/rules下创建规则⽂件customer-rules.drl

package rules 
import com.chenj.entity.*; 
//测试contains规则 
rule "rule1" 
when 
$order:Order(); 
$customer:Customer(orderList contains $order); 
then 
System.out.println("测试contains规则触发:"+$customer.getName()); 
end 
//测试not contains规则 
rule "rule2" 
when 
$order:Order(); 
$customer:Customer(orderList not contains $order); 
then 
System.out.println("测试not contains规则触发:"+$customer.getName()); 
end 
//测试⽐较操作符matches 
rule "rule3" 
when 
Customer(name matches "张.*") 
then 
System.out.println("测试⽐较操作符matches触发..."); 
end 
//测试⽐较操作符not matches 
rule "rule4" 
when 
Customer(name not matches "张.*") 
then 
System.out.println("测试⽐较操作符not matches触发..."); 
end 

第三步:编写单元测试

@Test 
public void test2(){ 
KieServices kieServices = KieServices.Factory.get(); 
KieContainer kieContainer = 
kieServices.getKieClasspathContainer(); 
//会话对象,⽤于和规则引擎交互 
KieSession kieSession = kieContainer.newKieSession(); 
//构造订单对象,设置订单⾦额,由规则引擎计算获得的积分 
Order order = new Order(); 
//匹配规则:$order:Order(); 
kieSession.insert(order); 
Customer customer = new Customer(); 
List<Order> orderList = new ArrayList<>(); 
//匹配规则: $customer:Customer(orderList contains $order); 
//orderList.add(order); 
customer.setOrderList(orderList); 
customer.setName("Jack"); 
//将数据交给规则引擎,规则引擎会根据提供的数据进⾏规则匹配 
kieSession.insert(customer); 
//激活规则引擎,如果匹配成功则执⾏规则 
kieSession.fireAllRules(); 
//关闭会话 
kieSession.dispose(); 
} 

在 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 容易发⽣死循环

//Drools提供的内置⽅法insert
rule “rule5”
when
eval(true); //默认成⽴
then
Customer cus=new Customer();
cus.setName(“张三”);
insert(cus);
System.out.println(“测试Drools提供的内置⽅法insert 触发…”);
end
rule “rule6”
when
c u s t o m e r : C u s t o m e r ( n a m e = = " 张三 " ) ; t h e n S y s t e m . o u t . p r i n t l n ( " 测试 D r o o l s 提供的内置⽅法 i n s e r t 触发 . . . " + customer:Customer(name =="张三"); then System.out.println("测试Drools提供的内置⽅法insert 触 发..."+ customer:Customer(name=="张三");thenSystem.out.println("测试Drools提供的内置insert触发..."+customer.getName());
end

测试:
@Test
public void test3(){
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer =
kieServices.getKieClasspathContainer();
//会话对象,⽤于和规则引擎交互
KieSession kieSession = kieContainer.newKieSession();
//激活规则引擎,如果匹配成功则执⾏规则
kieSession.fireAllRules();
//关闭会话
kieSession.dispose();
}

2.Update
update函数意义与其名称⼀样, ⽤来实现对当前Working Memory当中的 Fact进⾏更新,⽤来告诉当 前的 Working Memory 该 Fact 对象已经发⽣了变化
示例:
rule “rule7”
//no-loop true
when
$customer:Customer(name ==“李四”);
then
c u s t o m e r . s e t N a m e ( " 张三 " ) ; u p d a t e ( customer.setName("张三"); update( customer.setName("张三");update(customer);
System.out.println(“测试Drools提供的内置⽅法update 触发…”);
end
rule “rule8”
when
c u s t o m e r : C u s t o m e r ( n a m e = = " 张三 " ) ; t h e n S y s t e m . o u t . p r i n t l n ( " 测试 D r o o l s 提供的内置⽅法 u p d a t e 触发 . . . " + customer:Customer(name =="张三"); then System.out.println("测试Drools提供的内置⽅法update 触 发..."+ customer:Customer(name=="张三");thenSystem.out.println("测试Drools提供的内置update触发..."+customer.getName());
end

测试
@Test
public void test3(){
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer =
kieServices.getKieClasspathContainer();
//会话对象,⽤于和规则引擎交互
KieSession kieSession = kieContainer.newKieSession();
Customer customer = new Customer();
customer.setName(“李四”);
kieSession.insert(customer);
//激活规则引擎,如果匹配成功则执⾏规则
kieSession.fireAllRules();
//关闭会话
kieSession.dispose();
}

3.retract
retract⽤来将 Working Memory 当中某个 Fact 对象从 Working Memory 当中删除
//Drools提供的内置⽅法retract
rule “rule9”
when
c u s t o m e r : C u s t o m e r ( n a m e = = " 李四 " ) ; t h e n / / r e t r a c t ( customer:Customer(name =="李四"); then //retract( customer:Customer(name=="李四");then//retract(customer);
System.out.println(“测试Drools提供的内置⽅法retract 触发…”);
end
rule “rule10”
when
c u s t o m e r : C u s t o m e r ( ) ; t h e n S y s t e m . o u t . p r i n t l n ( " 测试 D r o o l s 提供的内置⽅法 r e t r a c t 触发 . . . " + customer:Customer(); then System.out.println("测试Drools提供的内置⽅法retract 触 发..."+ customer:Customer();thenSystem.out.println("测试Drools提供的内置retract触发..."+customer.getName());
end

测试
@Test
public void test3(){
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer =
kieServices.getKieClasspathContainer();
//会话对象,⽤于和规则引擎交互
KieSession kieSession = kieContainer.newKieSession();
Customer customer = new Customer();
customer.setName(“李四”);
kieSession.insert(customer);
//激活规则引擎,如果匹配成功则执⾏规则
kieSession.fireAllRules();
//通过规则过滤器实现只执⾏指定规则
//kieSession.fireAllRules(new
RuleNameEqualsAgendaFilter(“rule5”));
//关闭会话
kieSession.dispose();
}

属性部分
Drools中提供的属性如下表:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/136814.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript系列从入门到精通系列第一篇:JavaScript语言简介和它代码初体验

一&#xff1a;简介 1&#xff1a;起源 JavaScript诞生于1995年&#xff0c;它的出现主要是用于处理网页中的前端验证&#xff0c; 所谓的前端验证&#xff0c;就是指检查用户输入的内容是否符合一定的规则。 2&#xff1a;简史 JavaScript是由网景公司发明&#xff0c;起初命…

【SpringMVC】拦截器JSR303的使用

【SpringMVC】拦截器&JSR303的使用 1.1 什么是JSR3031.2 为什么使用JSR3031.3 常用注解1.4 Validated与Valid区别1.5 JSR快速入门1.5.2 配置校验规则# 1.5.3 入门案例二、拦截器2.1 什么是拦截器2.2 拦截器与过滤器2.3 应用场景2.4 拦截器快速入门2.5.拦截器链2.6登录案列权…

ZTMap是如何在相关政策引导下让建筑更加智慧化的?

近几年随着智慧楼宇概念的深入&#xff0c;尤其是在“十四五规划”“新基建”“数字经济”等相关战略和政策的引导下&#xff0c;智慧楼宇也迎来了快速发展期&#xff0c;对推动智慧城市系统的建设越来越重要。那么究竟什么是智慧楼宇呢&#xff1f;智慧楼宇其实就是整合楼宇内…

神经元量子点处理器赋能,三星QN85Z电视带来高品质视听盛宴

我们注意到近期三星发布新款Neo QLED电视QN85Z&#xff0c;有感于三星在芯片、面板技术等方面的深厚积累&#xff0c;我们对三星新发布的这款电视相当感兴趣。QN85Z新品搭载了三星“集成之芯”——神经元量子点处理器&#xff0c;搭配高端量子点Mini LED带来更为优化的画质和音…

IPV4和IPV6,公网IP和私有IP有什么区别?

文章目录 1、什么是IP地址&#xff1f;1.1、背景1.2、交换机1.3、局域网1.4、广域网1.5、ISP 互联网服务提供商 2、IPV42.1、什么是IPV4&#xff1f;2.2、IPV4的组成2.3、NAT 网络地址转换2.4、端口映射 3、公网IP和私有IP4、IPV6 1、什么是IP地址&#xff1f; 1.1、背景 一台…

机器人如何有效采摘苹果?

摘要&#xff1a;本文利用动捕数据构建拟人运动模型&#xff0c;对比观察两种苹果采摘模式&#xff0c;并对系统性能进行全面评估&#xff0c;为提高机器人采摘效率提供创新方法。 近期&#xff0c;一项关于苹果采摘机器人的有趣研究—— "Design and evaluation of a rob…

Git学习笔记8

Gitlab&#xff1a; Gitlab是利用Ruby on Rails 一个开源的版本管理系统&#xff0c;实现一个自托管的git项目仓库&#xff0c;可通过web界面进行访问公开或私有的项目。 Gitlab安装&#xff1a; 安装之前&#xff0c;将虚拟机的内存改成了4个G。内存如果太小&#xff0c;会有…

巧用“加减乘除”,停车场“碳”出节能发展新路

“绿色化、低碳化是高质量发展的关键”。中国电信以先驱姿态&#xff0c;积极贯彻“碳达峰碳中和”国家战略&#xff0c;以科技为画笔&#xff0c;绿色生态为底色&#xff0c;绘就节能低碳发展新蓝图。 在湖北省某办公楼宇&#xff0c;物业管理员因停车场照明现状发了愁。在过去…

Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

Unity 开发人员的城堡游戏引擎概述 一、简介2. Unity相当于什么GameObject&#xff1f;3. 如何设计一个由多种资产、生物等组成的关卡&#xff1f;4. 在哪里放置特定角色的代码&#xff08;例如生物、物品&#xff09;&#xff1f;Unity 中“向 GameObject 添加 MonoBehaviour”…

1_图神经网络GNN基础知识学习

文章目录 安装PyTorch Geometric安装工具包 在KarateClub数据集上使用图卷积网络 (GCN) 进行节点分类两个画图函数Graph Neural Networks数据集&#xff1a;Zacharys karate club network.PyTorch Geometric数据集介绍 edge_index使用networkx可视化展示 Graph Neural Networks…

element-table出现错位解决方法

先看示例图&#xff0c;这个在开发中还是很常遇到的&#xff0c;在table切换不同数据时或者切换页面时&#xff0c;容易出现&#xff1a; 解决方法很简单&#xff0c;官方有提供方法&#xff1a; 我们可以在重新渲染数据后&#xff1a; this.$nextTick(() > {this.$refs.…

嵌入式笔试面试刷题(day15)

文章目录 前言一、Linux中的主设备号和次设备号1.查看方法2.主设备号和次设备号的作用 二、软件IIC和硬件IIC的区别三、变量的声明和定义区别四、static在C和C中的区别五、串口总线空闲时候的电平状态总结 前言 本篇文章继续讲解嵌入式笔试面试刷题&#xff0c;希望大家坚持跟…

【超实用】2023年,学生上班族如何简单快速,低成本的搭建一个博客网站

文章目录 前言实操环节香港虚拟机购买博客搭建ssl证书配置备份设置 总结 前言 因为工作和生活的需要&#xff0c;我一直有博客的搭建需求。我将总结下来&#xff0c;为读者提供参考。  起初&#xff0c;我采用的是香港云虚拟主机&#xff0c;这种虚拟机极其便宜&#xff08;一…

什么样的应用程序适合使用Flutter开发桌面?

桌面应用开发的现状 在过去&#xff0c;桌面应用程序的开发通常需要使用特定于操作系统的工具和语言&#xff0c;如C、C#、Java等。这导致了高昂的开发成本和维护困难。尽管有一些跨平台桌面开发工具&#xff0c;如Electron和Qt&#xff0c;但它们在性能、用户体验和开发效率方…

Linux Static Key原理与应用

文章目录 背景1. static-key的使用方法1.1. static-key定义1.2 初始化1.3 条件判断1.4 修改判断条件 2、示例代码参考链接 背景 内核中有很多判断条件在正常情况下的结果都是固定的&#xff0c;除非极其罕见的场景才会改变&#xff0c;通常单个的这种判断的代价很低可以忽略&a…

Python3 语法简明教程

目录 0 前言1 输出语句、注释1.1 输出语句1.2 单行、多行注释 2 变量与对象、输入语句2.1 变量与对象2.2 数字类型和运算符2.3 输入语句 3 条件控制、循环语句3.1 条件控制3.2 循环语句3.2.1 while...else3.2.2 for...else 4 字典5 元组、列表5.1 元组5.2 列表 6 集合、推导式6…

C语言——贪吃蛇小游戏

目录 一、ncurse 1.1 为什么需要用ncurse&#xff1a; 1.2 ncurse的输入输出&#xff1a; 1.2.1 如何使用ncurse&#xff1a; 1.2.2 编译ncurse的程序&#xff1a; 1.2.3 测试输入一个按键ncurse的响应速度&#xff1a; 1.3 ncurse上下左右键获取&#xff1a; 1.3.1 如…

【IntelliJ IDEA】cmd和idea Terminal查看java版本不一致

问题描述 原来win10电脑上安装的是jdk8的版本&#xff0c;因某些原因&#xff0c;现在想换成jdk7的版本&#xff0c;修改环境变量后&#xff0c;在cmd中执行 [java -version]命令&#xff0c;显示的是7的版本。 但在idea的Terminal中执行&#xff0c;确实显示8的版本。 原因分…

基于深度强化学习的四旋翼无人机航线跟随

源自&#xff1a;指挥与控制学报 作者&#xff1a;杨志鹏 李波 甘志刚 梁诗阳 摘 要 针对无人机在空中执行航线跟随任务时无法对未知环境作出合理应对措施等问题, 提出了一种基于深度强化学习的四 旋翼无人机航线跟随方法. 通过无人机受力分析、欧拉角变换建立四旋翼无人…

2023.9.18 网络层 IP 协议详解

目录 IP协议 IPv4 32位 源IP 地址 / 32位 目的IP 地址 IP 地址管理 特殊 IP 路由选择 IP协议 IPv4 32位 源IP 地址 / 32位 目的IP 地址 基本知识&#xff1a; 在 IP 报头中一般表示为 32位 二进制整数日常生活中的 IP 一般将 32位 二进制整数&#xff0c;也就是 4字节 的二…