参考:规则引擎 Drools:决策表_jueyinga的博客-CSDN博客_drools 决策表

一、规则引擎 Drools:决策表

Drools除了支持drl形式的文件外还支持xls格式的文件(即Excel文件)。这种xls格式的文件通常称为决策表(decision table)。

决策表(decision table)是一个“精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。决策表与现有的drl文件可以无缝替换。Drools提供了相应的API可以将xls文件编译为drl格式的字符串。

1.1 决策表:


决策表语法:

关键字 说明 是否必须
RuleSet 相当于drl文件中的package 必须,只能有一个。如果没有设置RuleSet对应的值则使用默认值rule_table
Sequential 取值为Boolean类型。true表示规则按照表格自上到下的顺序执行,false表示乱序 可选
Import 相当于drl文件中的import,如果引入多个类则类之间用逗号分隔 可选
Variables 相当于drl文件中的global,用于定义全局变量,如果有多个全局变量则中间用逗号分隔 可选
RuleTable 它指示了后面将会有一批rule,RuleTable的名称将会作为以后生成rule的前缀 必须
CONDITION 规则条件关键字,相当于drl文件中的when。下面两行则表示 LHS 部分,第三行则为注释行,不计为规则部分,从第四行开始,每一行表示一条规则 每个规则表至少有一个
ACTION 规则结果关键字,相当于drl文件中的then 每个规则表至少有一个
NO-LOOP 相当于drl文件中的no-loop 可选
AGENDA-GROUP 相当于drl文件中的agenda-group 可选

在决策表中还经常使用到占位符,语法为$后面加数字,用于替换每条规则中设置的具体值。

上面的决策表例子转换为drl格式的规则文件内容如下:

package rules.excels;
//generated from Decision Table
import com.ppl.demo.entity.Account;
import java.util.List;
import java.util.ArrayList;
global List<String> list;
// rule values at B11, header at B6
rule "ExcelTable_11"salience 65535agenda-group "rule-group-001"when$account: Account(sex != "女")thenlist.add("性别不对");
end// rule values at B12, header at B6
rule "ExcelTable_12"salience 65534agenda-group "rule-group-001"when$account: Account(age < 22 || age> 28)thenlist.add("年龄不合适");
end// rule values at B13, header at B6
rule "ExcelTable_13"salience 65533agenda-group "rule-group-002"when$account: Account(balance < 1000)thenlist.add("工资太低");
end

Drools提供的将xls文件编译为drl格式字符串的API如下:

 @DisplayName("Excel To Rule")@Testpublic void testExceltoRule() {String realPath = "D:\\IDEA_Work\\excelrule001.xls";//指定决策表xls文件的磁盘路径File file = new File(realPath);InputStream is = null;try {is = new FileInputStream(file);} catch (FileNotFoundException e) {throw new RuntimeException(e);}SpreadsheetCompiler compiler = new SpreadsheetCompiler();String drl = compiler.compile(is, InputType.XLS);System.out.println(drl);}

Drools还提供了基于drl格式字符串创建KieSession的API:

KieHelper kieHelper = new KieHelper();
kieHelper.addContent(drl, ResourceType.DRL);
KieSession kieSession = kieHelper.build().newKieSession();

1.2 相关代码

package com.ppl.demo.entity;public class Account {private long accountno;private double balance;private String sex;private int age;public Account(long accountno, double balance) {super();this.accountno = accountno;this.balance = balance;}public Account() {super();// TODO Auto-generated constructor stub}public long getAccountno() {return accountno;}public void setAccountno(long accountno) {this.accountno = accountno;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Account{" +"accountno=" + accountno +", balance=" + balance +", sex='" + sex + '\'' +", age=" + age +'}';}
}

测试类:

package com.ppl.demo;import com.ppl.demo.entity.Account;
import com.ppl.demo.utils.KnowledgeSessionHelper;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.junit.jupiter.api.*;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
import org.springframework.boot.test.context.SpringBootTest;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;@SpringBootTest
@DisplayName("junit5功能测试")
class RuleExcelsTests {static KieContainer kieContainer;StatelessKieSession sessionStateless = null;KieSession sessionStatefull = null;@BeforeEachvoid testBeforeEach() {kieContainer = KnowledgeSessionHelper.createRuleBase();System.out.println("测试就要开始。。。");}@AfterEachvoid testAfterEach() {System.out.println("测试就要结束。。。");}@BeforeAllstatic void testBeforeAll() {System.out.println("所有测试就要开始。。。");}@AfterAllstatic void testAfterAll() {System.out.println("所有测试已经结束。。。");}@DisplayName("Excel Rule")@Testpublic void testExcelRule() {sessionStatefull = KnowledgeSessionHelper.getStatefulKnowledgeSession(kieContainer, "lesson5-session");//设置全局变量,名称和类型必须和规则文件中定义的全局变量名称对应List<String> list = new ArrayList();sessionStatefull.setGlobal("list",list);Account account = new Account();account.setBalance(300D);account.setAge(35);account.setSex("男");sessionStatefull.insert(account);sessionStatefull.getAgenda().getAgendaGroup("rule-group-001").setFocus();int count=sessionStatefull.fireAllRules();//激活规则引擎,如果规则匹配成功则执行规则System.out.println("用户balance:"+account.getBalance());System.out.println("list:"+list);//关闭会话System.out.println("总共执行了: "+count+" 条规则");sessionStatefull.dispose();}@DisplayName("Excel To Rule")@Testpublic void testExceltoRule() {String realPath = "D:\\IDEA_Work\\excelrule001.xls";//指定决策表xls文件的磁盘路径File file = new File(realPath);InputStream is = null;try {is = new FileInputStream(file);} catch (FileNotFoundException e) {throw new RuntimeException(e);}SpreadsheetCompiler compiler = new SpreadsheetCompiler();String drl = compiler.compile(is, InputType.XLS);System.out.println(drl);}
}

POM文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ppl</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version><drools.version>7.73.0.Final</drools.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><!--drools规则引擎--><dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-templates</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.kie</groupId><artifactId>kie-api</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-decisiontables</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.kie</groupId><artifactId>kie-spring</artifactId><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId></exclusion><exclusion><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId></exclusion><exclusion><groupId>org.springframework</groupId><artifactId>spring-core</artifactId></exclusion><exclusion><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></exclusion></exclusions><version>${drools.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><scope>compile</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

agenda-group关键字说明

  • 没有被focus的规则分组会运行规则条件,不运行规则结果。

  • 详细说明可能遇到情况,如果一个kieSession有多个规则,每个规则都包含agenda-group关键字,且值不完全一样会出现以下的情况,auto-focus没有配置的情况。

  • 直接fireAllRules,所有规则会运行一遍条件,也就是when到then中间的部分,不会运行结果,then后的部分。

  • focus某一个agenda-group,所有规则会运行一遍条件,也就是when到then中间的部分,只运行focus规则的结果部分。

  • 我的处理方案:将不同agenda-group的规则放在不同的KieBase中,保证每一个KieSession中只有一个agenda-group的数据。因为我的条件部分调用了很多工具类,如果都运行一遍会影响效率。

其他示例:

决策表转换成drl文件代码:

package rules.decision.tables;
//generated from Decision Table
import java.lang.StringBuilder;
import com.ppl.demo.entity.Student;
global java.lang.StringBuilder resultsInfo;// rule values at B15, header at B10
rule "student-score-name-1"
/* 1、姓名为张三的特殊处理
2、自定义规则的名字 */salience 65535activation-group "score"when$stu: Student(name == "张三")thenresultsInfo.append("张三特殊处理:");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");resultsInfo.append("优");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end// rule values at B16, header at B10
rule "student-score_16"salience 65534activation-group "score"when$stu: Student(name == "李四", score > 0 && score < 60)thenresultsInfo.append("李四部分特殊处理:");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");resultsInfo.append("一般");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end// rule values at B17, header at B10
rule "student-score_17"salience 65533activation-group "score"when$stu: Student(score > 0 && score < 60)thenresultsInfo.append("不及格");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end// rule values at B18, header at B10
rule "student-score_18"salience 65532activation-group "score"when$stu: Student(score > 60 && score < 70)thenresultsInfo.append("一般");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end// rule values at B19, header at B10
rule "student-score_19"salience 65531activation-group "score"when$stu: Student(score > 70 && score < 90)thenresultsInfo.append("良好");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end// rule values at B20, header at B10
rule "student-score_20"salience 65530activation-group "score"when$stu: Student(score > 90 && score < 100)thenresultsInfo.append("优");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end

测试代码

@DisplayName("Excel decision.tables")@Testpublic void testExcelDecisionTables() {// 张三虽然只得20分,但是根据规则判断,结果应该是  优invokedDecisionTable(new Student("张三", 20));// 李四虽然只得20分,但是根据规则判断,结果应该是  一般invokedDecisionTable( new Student("李四", 20));// 李四得75分,但是根据规则判断,结果应该是  良好invokedDecisionTable( new Student("李四", 75));// 王五得59分,但是根据规则判断,结果应该是  不及格invokedDecisionTable( new Student("王五", 59));// 赵六得20分,但是根据规则判断,结果应该是  一般invokedDecisionTable( new Student("赵六", 65));// 钱七得20分,但是根据规则判断,结果应该是  良好invokedDecisionTable( new Student("钱七", 75));// 李八得20分,但是根据规则判断,结果应该是  优invokedDecisionTable(new Student("李八", 95));}public void invokedDecisionTable(Student student) {System.out.println("\r");sessionStatefull = KnowledgeSessionHelper.getStatefulKnowledgeSession(kieContainer, "lesson6-session");StringBuilder result = new StringBuilder();sessionStatefull.setGlobal("resultsInfo", result);sessionStatefull.insert(student);int count=sessionStatefull.fireAllRules();//激活规则引擎,如果规则匹配成功则执行规则System.out.println("总共执行了: "+count+" 条规则");sessionStatefull.dispose();System.out.println("规则执行结果:" + result);}


打印日志如下:

规则:student-score-name-1 执行了.
规则:student-score-name-1 执行了.
总共执行了: 1 条规则
规则执行结果:张三特殊处理:优规则:student-score_16 执行了.
规则:student-score_16 执行了.
总共执行了: 1 条规则
规则执行结果:李四部分特殊处理:一般规则:student-score_19 执行了.
总共执行了: 1 条规则
规则执行结果:良好规则:student-score_17 执行了.
总共执行了: 1 条规则
规则执行结果:不及格规则:student-score_18 执行了.
总共执行了: 1 条规则
规则执行结果:一般规则:student-score_19 执行了.
总共执行了: 1 条规则
规则执行结果:良好规则:student-score_20 执行了.
总共执行了: 1 条规则
规则执行结果:优

规则引擎 Drools--决策表(Decision Table)使用简介相关推荐

  1. 规则引擎drools系列(一)

    规则引擎 Drools 1. 问题引出 现有一个在线申请信用卡的业务场景,用户需要录入个人信息,如下图所示: //此处为伪代码 ​ //检查用户信息合法性,返回true表示检查通过,返回false表示 ...

  2. 开源规则引擎 drools

    前言 在很多企业的 IT 业务系统中,经常会有大量的业务规则配置,而且随着企业管理者的决策变化,这些业务规则也会随之发生更改.为了适应这样的需求,我们的 IT 业务系统应该能快速且低成本的更新.适应这 ...

  3. 规则引擎Drools在贷后催收业务中的应用

    作者:vivo 互联网服务器团队- Feng Xiang 在日常业务开发工作中我们经常会遇到一些根据业务规则做决策的场景.为了让开发人员从大量的规则代码的开发维护中释放出来,把规则的维护和生成交由业务 ...

  4. java排班_使用java规则引擎Drools自动排班前言.doc

    使用java规则引擎Drools自动排班前言 使用java规则引擎Drools自动排班前言本文以一个经简化的运输车队自动排班需求为例,详细讲解了如何使用java规则引擎Drools进行商业规则的形式语 ...

  5. 规则引擎 Drools

    规则引擎 Drools 文章目录 规则引擎 Drools 1. 问题引出 2. 规则引擎概述 2.1 什么是规则引擎 2.2 使用规则引擎的优势 2.3 规则引擎应用场景 2.4 Drools介绍 3 ...

  6. 规则引擎——Drools

    Drools简介 Drools使用范例 语法介绍 名词解释 Drools简介   JBoss Rules 的前身是Codehaus的一个开源项目叫Drools.最近被纳入JBoss门下,更名为JBos ...

  7. 【Drools一】值得打工人学习的规则引擎Drools

    本文主要对Drools的使用业务场景做简单介绍. 规则引擎 规则引擎:全称为业务规则管理系统,英文名为BRMS(即Business Rule Management System).规则引擎的主要思想是 ...

  8. 别再说你不会,规则引擎Drools了

    一.为什么要使用规则引擎 有一天运营想弄一个积分策略,计算额外积分金额 ,规则如下: 订单原价金额 100以下, 不加分: 100-500 加100分: 500-1000 加500分: 1000 以上 ...

  9. 规则引擎Drools详细介绍

    规则引擎Drools详细介绍 一. 规则引擎概述 1.1 什么是规则引擎 1.2 使用规则引擎的优势 1.3 规则引擎应用场景 1.4 Drools介绍 二. Drools使用与说明 2.1 Droo ...

最新文章

  1. 北京科技大学C语言程序设计,北京科技大学《C语言》第1章.ppt
  2. android fragmentstatepageradapter框架,安卓爬坑指南之FragmentStatePagerAdapter
  3. java测试netty_《Netty官方文档》基准测试
  4. 精选的一些《编程之美》相关资料
  5. Github | 机器人工具大全
  6. 在linux上禁用ip,防止frps转发的端口被爆破,并屏蔽境外ip
  7. Java面试题:热情盛夏,分享Java大厂面试百题
  8. GDPR法律条款解读及应对指南(全面版)
  9. selenium系列--测试脚本--将Excel文件用于测试(unittest数据驱动实战)
  10. Visual Studio 2008破解激活升级方法
  11. pc测试xbox精英手柄的软件,Xbox Elite手柄还是Steam手柄?一个PC玩家的手柄之路 篇二:偷懒拖更一万年,补上使用细节及软件部分的测评...
  12. 点到点(point-to-point) 与 端到端(end to end)
  13. 社交网络分析-中心性指标
  14. 如何精确理解leader布置的任务
  15. c语言实型变量允许存放整型数,实型变量允许存放整形数吗
  16. 关于FBB-FFD算法加速因子的证明
  17. 【HNOI 2018】毒瘤
  18. 理解本真的REST架构风格
  19. 【RPG黑暗之光】第四章· 物品模块
  20. android webView显示PDF文件

热门文章

  1. Cookie--防劫持的处理
  2. 网站js劫持了怎么处理和预防、js劫持了怎么办
  3. 什么是sku转载网上,备忘一个业务知识
  4. java中.的意思_java中“:”的意思是什么?
  5. MathType的下载和安装以及添加到word中
  6. 数值计算·第八集:二阶锥规划(CVXPY版)
  7. (R68s,R66s)OpenWRT设置ipv6网络(以光猫拨号场景为例)
  8. 解读CUDA Compiler Driver NVCC - Ch.2 - Compilation Phases
  9. 绘图和可视化(Python)
  10. 第四次计算革命孕育“数字经济体”