规则引擎 Drools:决策表

article/2025/8/24 18:45:23

规则引擎 Drools:决策表

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

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

决策表:

在这里插入图片描述
决策表语法:

关键字说明是否必须
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();

相关代码

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 条规则
规则执行结果:优

http://chatgpt.dhexx.cn/article/t5qacBZg.shtml

相关文章

决策表(决策树)-- homework

一、定义&#xff1a;决策表又称判断表&#xff0c;是一种呈表格状的图形工具&#xff0c;适用于描述处理判断条件较多&#xff0c;各条件又相互组合、有多种决策方案的情况。精确而简洁描述复杂逻辑的方式&#xff0c;将多个条件与这些条件满足后要执行动作相对应。但不同于传…

软件测试_决策表(Decision Table)

软件测试_因果图与决策表 决策表&#xff08;Decision Table) 定义 利用判定表设计测试用例集合的方法叫做判定表驱动分析法&#xff08;决策表法&#xff09;。 决策表测试 在所有的黑盒测试方法中&#xff0c;基于决策表的测试是最严格的、最具有逻辑性的测试方法。 决策表…

判定表法(决策表)-实验五例题-三角形决策表

判定表也称为决策表&#xff0c;其实质就是一种逻辑表。利用决策表可以设计出完整的测试用例集合。 下面通过一个“图书阅读指南”来制作一个决策表。图书阅读指南指明了图书阅读过程中可能出现的状况&#xff0c;以及针对各种情况给读者的建议。在图书阅读过程中可能会出现3 种…

测试设计之决策表

案例一、四边形4条边&#xff1a;a&#xff0c;b&#xff0c;c&#xff0c;d&#xff0c;其中a、c为对边&#xff0c;b、d为对边&#xff0c;根据条件判断四边形类型 条件&#xff1a;C1&#xff1a;a//c&#xff1b;C2&#xff1a;b//d&#xff1b;C3&#xff1a;ac&#xff1…

【软件工程】决策表和决策树

1.1决策表 1.1.1决策表的定义 决策表又称判断表&#xff0c;是一种呈表格状的图形工具&#xff0c;适用于描述处理判断条件较多&#xff0c;各条件又相互组合、有多种决策方案的情况。精确而简洁描述复杂逻辑的方式&#xff0c;将多个条件与这些条件满足后要执行动作相对应。…

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

参考&#xff1a;规则引擎 Drools&#xff1a;决策表_jueyinga的博客-CSDN博客_drools 决策表 一、规则引擎 Drools&#xff1a;决策表 Drools除了支持drl形式的文件外还支持xls格式的文件&#xff08;即Excel文件&#xff09;。这种xls格式的文件通常称为决策表&#xff08;d…

如何用决策表设计测试用例?

实际测试中&#xff0c;如果输入条件较多&#xff0c;再加上各种输人与输出之间相互的作用关系&#xff0c;画出的因果图会比较复杂&#xff0c;容易使人混乱。为了避免这种情况&#xff0c;人们往往使用决策表法代替因果图法。 决策表也称为判定表&#xff0c;其实质就是一严…

浅谈决策树与决策表

前言 在程序设计过程中&#xff0c;经常会出现多层逻辑控制的嵌套&#xff0c;而这样的嵌套关系往往会导致我们不能直观的看出程序的逻辑关系&#xff0c;这会导致在测试过程中比较容易出现遗漏。因此我们需要引入决策表、决策树&#xff0c;其中决策表就是设计逻辑控制时十分…

决策表法

决策表法介绍&#xff1a; >>在因果图法设计测试用例的步骤中“因果图转换成判定表”中已使用了判定表。判定表又称决策表&#xff0c;为决策表发的核心&#xff0c;是分析和表达 多逻辑条件下执行不同操作情况的有效工具。因此&#xff0c;决策表法是一种能够将复杂逻辑…

6.决策表

决策表的使用方式与使用drl规则文件基本一致&#xff0c;好处是可以把一些相关的规则以表格方式展示&#xff0c;便于阅读及维护 1.maven依赖 <!-- 决策表 --> <dependency><groupId>org.drools</groupId><artifactId>drools-decisiontables&l…

请根据以下需求使用决策表设计测试用例

任务3&#xff1a;请根据以下需求使用决策表设计测试用例 信用卡额度发放&#xff1a; 年收入小于2万&#xff0c;不发放信用卡&#xff1b; 2万<年收入<5万&#xff0c;无稳定工作&#xff0c;额度1万&#xff0c;有稳定工作额度3万&#xff1b; 5万<年收入<1…

决策表法用例设计

决策表法 在一些数据处理问题中,某些操作是否实施依赖于多个逻辑条件的取值。 也即在这些逻辑条件取值的组合所构成的多种情况下,分别执行不同的操作。 处理这类问题的一个非常有力的分析和表达工具是决策表,它可以很清楚地表达各种条件之间的复杂关系。 早在程序设计发…

决策表与决策树

决策表的定义&#xff1a; 决策表又称判断表&#xff0c;是一种呈表格状的图形工具&#xff0c;适用于描述处理判断条件较多&#xff0c;各条件又相互组合、有多种决策方案的情况。精确而简洁描述复杂逻辑的方式&#xff0c;将多个条件与这些条件满足后要执行动作相对应。但不…

决策表

决策表&#xff0c;也叫判定表。在所有的功能性测试方法中&#xff0c;基于决策表的测试方法被认为是最严格的&#xff0c;因为决策表具有逻辑严格性。 决策表是分析和表达多逻辑条件下执行不同操作的情况的工具。在程序设计发展的初期&#xff0c;决策表就已被用作编写程序的…

决策表法的应用

决策表的组成 决策表通常由以下4部分组成&#xff1a; 条件桩—列出问题的所有条件 条件项—针对条件桩给出的条件列出所有可能的取值 动作桩—列出问题规定的可能采取的操作 动作项—指出在条件项的各组取值情况下应采取的动作 条件桩条件项 …

什么是“决策表”?什么是“决策树”?

决策表&#xff1a; 决策表又称判断表&#xff0c;是一种呈表格状的图形工具&#xff0c;适用于描述处理判断条件较多&#xff0c;各条件又相互组合、有多种决策方案的情况。 在所有的功能性测试方法中&#xff0c;基于决策表的测试方法被认为是最严格的&#xff0c;因为决策…

功能测试技术——决策表法

一、决策表的概念 在一些数据处理问题当中&#xff0c;某些操作的实施依赖于多个逻辑条件的组合&#xff0c;即&#xff1a;针对不同逻辑条件的组合值&#xff0c;分别执行不同的操作。决策表就是分析和表达多逻辑条件下执行不同操作情况的工具。 二、决策表的组成 决策表通…

决策表(决策树)

1.什么是决策树 决策树是一种基本的分类与回归方法&#xff0c;在分类问题中&#xff0c;表示基于特征对实例进行分类的过程。它可以认为是if-then规则的集合&#xff0c;也可以认为是定义在特征空间与类空间上的条件概率分布&#xff0c;其主要优点是模型具有可读性&#xff0…

决策表是什么?怎么使用决策表?

实际测试中&#xff0c;如果输入条件较多&#xff0c;再加上各种输人与输出之间相互的作用关系&#xff0c;画出的因果图会比较复杂&#xff0c;容易使人混乱。为了避免这种情况&#xff0c;人们往往使用决策表法代替因果图法。 决策表也称为判定表&#xff0c;其实质就是一严…

二叉搜索树详解

写在前面 本文主要分为三个部分。 第一部分介绍了二叉搜索树的基本性质。 第二部分全面详细地讲述了二叉搜索树的各种基本操作。包括WALK/遍历、SEARCH/查找、MINIMUM/最小关键字、MAXIMUM/最大关键字、SUCCESSOR/后继、PREDECESSOR/前驱、INSERT/插入、DELETE/删除等。主要参考…