drools决策表的简单使用
一、背景
在之前的文章中,我们的业务规则都是写在了drl文件中,这对开发人员来说是没有什么问题,如果是业务人员则不怎么友好,这篇文章我们简单学习一下drools中决策表的使用,规则是写在excel文件中。
二、一个简单的决策表

在上面这个图中ResultSet和ResultTable是必须的,而且同一个包中,我们最好只上传一个决策表。
1、在同一个决策表中处理多个Sheet页

2、RuleSet下方可以有哪些属性
| Label | Value | Usage |
|---|---|---|
RuleSet |
The package name for the generated DRL file. Optional, the default is rule_table. |
Must be the first entry. |
Sequential |
true or false. If true, then salience is used to ensure that rules fire from the top down. |
Optional, at most once. If omitted, no firing order is imposed. |
SequentialMaxPriority |
Integer numeric value | Optional, at most once. In sequential mode, this option is used to set the start value of the salience. If omitted, the default value is 65535. |
SequentialMinPriority |
Integer numeric value | Optional, at most once. In sequential mode, this option is used to check if this minimum salience value is not violated. If omitted, the default value is 0. |
EscapeQuotes |
true or false. If true, then quotation marks are escaped so that they appear literally in the DRL. |
Optional, at most once. If omitted, quotation marks are escaped. |
IgnoreNumericFormat |
true or false. If true, then the format for numeric values is ignored, for example, percent and currency. |
Optional, at most once. If omitted, DRL takes formatted values. |
Import |
A comma-separated list of Java classes to import from another package. | Optional, may be used repeatedly. |
Variables |
Declarations of DRL globals (a type followed by a variable name). Multiple global definitions must be separated by commas. | Optional, may be used repeatedly. |
Functions |
One or more function definitions, according to DRL syntax. | Optional, may be used repeatedly. |
Queries |
One or more query definitions, according to DRL syntax. | Optional, may be used repeatedly. |
Declare |
One or more declarative types, according to DRL syntax. | Optional, may be used repeatedly. |
Unit |
The rule units that the rules generated from this decision table belong to. | Optional, at most once. If omitted, the rules do not belong to any unit. |
Dialect |
java or mvel. The dialect used in the actions of the decision table. |
Optional, at most once. If omitted, java is imposed. |
ResultSet:区域只可有一个。
3、RuleTable下方可以有哪些属性
| Label | Or custom label that begins with | Value | Usage |
|---|---|---|---|
NAME |
N | Provides the name for the rule generated from that row. The default is constructed from the text following the RuleTable tag and the row number. |
At most one column. |
DESCRIPTION |
I | Results in a comment within the generated rule. | At most one column. |
CONDITION |
C | Code snippet and interpolated values for constructing a constraint within a pattern in a condition. | At least one per rule table. |
ACTION |
A | Code snippet and interpolated values for constructing an action for the consequence of the rule. | At least one per rule table. |
METADATA |
@ | Code snippet and interpolated values for constructing a metadata entry for the rule. | Optional, any number of columns. |
具体的使用可以见上方的图
4、规则属性的编写
在ResultSet和ResultTable这个地方都可以编写规则属性。ResultSet地方的规则属性将影响同一个包下所有的规则,而ResultTable这个地方的规则属性,只影响这个规则。ResultTable的优先级更高。
支持的规则属性有:PRIORITY、DATE-EFFECTIVE、DATE-EXPIRES、NO-LOOP、AGENDA-GROUP、ACTIVATION-GROUP、DURATION、TIMER、CALENDAR、AUTO-FOCUS、LOCK-ON-ACTIVE、RULEFLOW-GROUP。
具体的用法:见上图中ACTIVATION-GROUP的使用。
三、需求
我们需要根据学生的成绩分数,给出相应的结果。规则如下:
特殊处理的规则:
规则一:只要名字是张三的,直接判定为 优
规则二:只要名字是李四的,如果分数在0,60之间,直接认为是一般
普通规则:
规则三:分数在0,60之间认为是不及格
规则四:分数在60,70之间认为是一般
规则五:分数在70,90之间认为是良好
规则六:分数在90,100之间认为是优
从上方的规则中,我们可以看到姓名为张三和李四的学生特殊处理了。
四、实现
1、项目实现结构图

2、引入jar包
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>7.69.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
<!-- 决策表 -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
3、编写kmodule.xml文件
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kabse" packages="rules.decision.tables" default="false">
<ksession name="ksession" default="false" type="stateful"/>
</kbase>
</kmodule>
4、编写学生实体类
@Getter
@Setter
@ToString
public class Student {
private String name;
// 分数只能在 0-100 之间
private Integer score;
public Student(String name, Integer score) {
this.name = name;
if (null == score || score < 0 || score > 100) {
throw new RuntimeException("分数只能在0-100之间");
}
this.score = score;
}
}
5、编写决策表

6、将决策表转换成drl文件
这步主要是为了查看我们的决策表编写的是否正确,看看最终生成的drl文件是什么样的。
1、决策表转换成drl文件代码
/**
* 决策表转换成 drl 文件
*/
public static void decisionTable2Drl() throws IOException {
Resource resource = ResourceFactory.newClassPathResource("rules/decision/tables/student-score.xlsx", "UTF-8");
InputStream inputStream = resource.getInputStream();
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(inputStream, InputType.XLS);
log.info("决策表转换的drl内容为:\r{}", drl);
// 验证一下 drl 文件是否有问题
KieHelper kieHelper = new KieHelper();
Results results = kieHelper.addContent(drl, ResourceType.DRL).verify();
List<Message> messages = results.getMessages(Message.Level.ERROR);
if (null != messages && !messages.isEmpty()) {
for (Message message : messages) {
log.error(message.getText());
}
}
}
2、转换成具体的drl文件为
package rules.decision.tables;
//generated from Decision Table
import java.lang.StringBuilder;
import com.huan.drools.Student;
global java.lang.StringBuilder resultsInfo;
// rule values at B15, header at B10
rule "student-score-name-1"
/* 1、姓名为张三的特殊处理
2、自定义规则的名字 */
salience 65535
activation-group "score"
when
$stu: Student(name == "张三")
then
resultsInfo.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 65534
activation-group "score"
when
$stu: Student(name == "李四", score > 0 && score < 60)
then
resultsInfo.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 65533
activation-group "score"
when
$stu: Student(score > 0 && score < 60)
then
resultsInfo.append("不及格");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end
// rule values at B18, header at B10
rule "student-score_18"
salience 65532
activation-group "score"
when
$stu: Student(score > 60 && score < 70)
then
resultsInfo.append("一般");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end
// rule values at B19, header at B10
rule "student-score_19"
salience 65531
activation-group "score"
when
$stu: Student(score > 70 && score < 90)
then
resultsInfo.append("良好");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end
// rule values at B20, header at B10
rule "student-score_20"
salience 65530
activation-group "score"
when
$stu: Student(score > 90 && score < 100)
then
resultsInfo.append("优");
System.out.println("规则:" + drools.getRule().getName() + " 执行了.");
end
从上方可以看出第一个规则的规则名称是不一样的,而且存在一些描述信息,这个是在决策表中特殊处理了。
7、测试
1、编写测试代码
package com.huan.drools;
import lombok.extern.slf4j.Slf4j;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.KieServices;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* drools 决策表的使用
*/
@Slf4j
public class DroolsDecisionTableApplication {
public static void main(String[] args) throws IOException {
decisionTable2Drl();
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.newKieClasspathContainer();
// 张三虽然只得20分,但是根据规则判断,结果应该是 优
invokedDecisionTable(kieContainer, new Student("张三", 20));
// 李四虽然只得20分,但是根据规则判断,结果应该是 一般
invokedDecisionTable(kieContainer, new Student("李四", 20));
// 李四得75分,但是根据规则判断,结果应该是 良好
invokedDecisionTable(kieContainer, new Student("李四", 75));
// 王五得59分,但是根据规则判断,结果应该是 不及格
invokedDecisionTable(kieContainer, new Student("王五", 59));
// 赵六得20分,但是根据规则判断,结果应该是 一般
invokedDecisionTable(kieContainer, new Student("赵六", 65));
// 钱七得20分,但是根据规则判断,结果应该是 良好
invokedDecisionTable(kieContainer, new Student("钱七", 75));
// 李八得20分,但是根据规则判断,结果应该是 优
invokedDecisionTable(kieContainer, new Student("李八", 95));
}
public static void invokedDecisionTable(KieContainer kieContainer, Student student) {
System.out.println("\r");
KieSession kieSession = kieContainer.newKieSession("ksession");
StringBuilder result = new StringBuilder();
kieSession.setGlobal("resultsInfo", result);
kieSession.insert(student);
kieSession.fireAllRules();
kieSession.dispose();
System.out.println("规则执行结果:" + result);
}
/**
* 决策表转换成 drl 文件
*/
public static void decisionTable2Drl() throws IOException {
Resource resource = ResourceFactory.newClassPathResource("rules/decision/tables/student-score.xlsx", "UTF-8");
InputStream inputStream = resource.getInputStream();
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(inputStream, InputType.XLS);
log.info("决策表转换的drl内容为:\r{}", drl);
// 验证一下 drl 文件是否有问题
KieHelper kieHelper = new KieHelper();
Results results = kieHelper.addContent(drl, ResourceType.DRL).verify();
List<Message> messages = results.getMessages(Message.Level.ERROR);
if (null != messages && !messages.isEmpty()) {
for (Message message : messages) {
log.error(message.getText());
}
}
}
}
2、测试结果

从上图中可知,我们的规则都正常执行了。
五、完整代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-decision-table
六、参考文档
drools决策表的简单使用的更多相关文章
- drools决策表的使用
决策表我们在drools规则引擎初探里做了简单介绍,这里主要是介绍如何通过java代码来把这个excel文件和drools关联起来,如何使其达到我们想要的效果. 这里假设我们在resources目录下 ...
- drools的简单入门案例
一.背景 最近在学习规则引擎drools,此处简单记录一下drools的入门案例. 二.为什么要学习drools 假设我们存在如下场景: 在我们到商店购买衣服的时候,经常会发生这样的事情,购买1件不打 ...
- Drools文档(六) 用户手册
用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...
- Drools 7.4.1.Final参考手册(六) 用户手册
用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...
- 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误
一.背景 当前自己开发的 Android 项目是一个智能推荐系统,用到 drools 规则引擎,于我来说是一个新知识点,以前都没听说过的东东,不过用起来也不算太难,经过一段时间学习,基本掌握.关于 d ...
- drools中then部分的写法
目录 1.背景 2.支持的方法 2.1 insert 插入对象到工作内存中 2.1.1 需求 2.1.2 drl文件编写 2.1.3 部分java代码编写 2.1.4 运行结果 2.1.5 结论 2. ...
- 用ACE来写代码
写在前面 在很多时候,我们想用一个支持高亮的WEB编辑器来做规则配置.代码编辑等,此时ACE应该是一个不错的选择,简单的用法如下: <!DOCTYPE html> <html lan ...
- Drools简单例子
转自:http://www.blogjava.net/diggbag/articles/359347.html 1.Drools简单例子 首先是搭建一个可供进行Drools开发的框架.Jboss官方推 ...
- 规则引擎drools的简单使用
规则引擎适用于有复杂多变的规则,如商品满减.积分赠送.考勤规则等 一.引入maven依赖 <dependency> <groupId>org.drools</groupI ...
随机推荐
- potoshop cs6安装配置16错误解决办法(win10系统)
问题截图如下: 解决方法: 右击图标选择属性:选择兼容性-->兼容模式-->以管理员身份运行-->应用 然后就可以打开了!
- npm权限不够(安装什么都报错)
问题 Windows下使用npm安装任何包都报错, Windows下使用npm显示权限不够 如图: 解决方法 1. 方法一 使用管理员权限打开 命令窗口, 治标不治本!!!!不推荐 ...
- 【零碎小bug系列】安卓开发是遇到空指针异常java.lang.NullPointerException: Attempt to invoke...
安卓开发是遇到空指针异常 java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable ...
- thymeleaf的具体语法
thymeleaf模板引擎是什么?请点击我查看 文章目录 thymeleaf模板引擎是什么?请点击我查看 代码 该实例代码延续[thymeleaf模板引擎](https://blog.csdn.net ...
- MongoDB 支持地理空间数据存储
MongoDB 支持地理空间数据存储 官方文档 https://docs.mongodb.com/manual/geospatial-queries/ MongoDB 支持对于地理空间数据的查询操作. ...
- echarts饼图禁止鼠标悬浮区块突出
禁止悬浮突出,在series内添加hoverAnimation:false即可 代码如下: option = { color:['#3498db','#EEEEEE'], series: [ { na ...
- 十、包机制与JavaDoc
一.包机制 为了更好的组织类,Java提供了包机制,用于区别类名的命名空间. 包语句的语句格式为: package pkg1[. pkg2[. pkg3...]]; 一般使用公司域名倒置作为包名:例如 ...
- 微服务状态之python巡查脚本开发
背景 由于后端微服务架构,于是各种业务被拆分为多个服务,服务之间的调用采用RPC接口,而Nacos作为注册中心,可以监听多个服务的状态,比如某个服务是否down掉了.某个服务的访问地址是否改变.以及流 ...
- SMTP协议解读以及如何使用SMTP协议发送电子邮件
电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件.SMTP的全称为Simple Mail Transfer Protocol,也就是简单邮件传输协议,字如其名. 相较于POP3而言 ...
- Linux(ubuntu)二进制安装mysql8.0
mysql官方网站下载地址:https://dev.mysql.com/downloads/mysql/ 1.创建mysql运行用户和组 groupadd -g 1001 mysql useradd ...