一、背景

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

二、一个简单的决策表

在上面这个图中ResultSetResultTable是必须的,而且同一个包中,我们最好只上传一个决策表。

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、规则属性的编写

ResultSetResultTable这个地方都可以编写规则属性。ResultSet地方的规则属性将影响同一个包下所有的规则,而ResultTable这个地方的规则属性,只影响这个规则。ResultTable的优先级更高。

支持的规则属性有:PRIORITYDATE-EFFECTIVEDATE-EXPIRESNO-LOOPAGENDA-GROUPACTIVATION-GROUPDURATIONTIMERCALENDARAUTO-FOCUSLOCK-ON-ACTIVERULEFLOW-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

六、参考文档

1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#decision-tables-con_decision-tables

drools决策表的简单使用的更多相关文章

  1. drools决策表的使用

    决策表我们在drools规则引擎初探里做了简单介绍,这里主要是介绍如何通过java代码来把这个excel文件和drools关联起来,如何使其达到我们想要的效果. 这里假设我们在resources目录下 ...

  2. drools的简单入门案例

    一.背景 最近在学习规则引擎drools,此处简单记录一下drools的入门案例. 二.为什么要学习drools 假设我们存在如下场景: 在我们到商店购买衣服的时候,经常会发生这样的事情,购买1件不打 ...

  3. Drools文档(六) 用户手册

    用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...

  4. Drools 7.4.1.Final参考手册(六) 用户手册

    用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...

  5. 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误

    一.背景 当前自己开发的 Android 项目是一个智能推荐系统,用到 drools 规则引擎,于我来说是一个新知识点,以前都没听说过的东东,不过用起来也不算太难,经过一段时间学习,基本掌握.关于 d ...

  6. 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. ...

  7. 用ACE来写代码

    写在前面 在很多时候,我们想用一个支持高亮的WEB编辑器来做规则配置.代码编辑等,此时ACE应该是一个不错的选择,简单的用法如下: <!DOCTYPE html> <html lan ...

  8. Drools简单例子

    转自:http://www.blogjava.net/diggbag/articles/359347.html 1.Drools简单例子 首先是搭建一个可供进行Drools开发的框架.Jboss官方推 ...

  9. 规则引擎drools的简单使用

    规则引擎适用于有复杂多变的规则,如商品满减.积分赠送.考勤规则等 一.引入maven依赖 <dependency> <groupId>org.drools</groupI ...

随机推荐

  1. 面试题:给你个id,去拿到name,多叉树遍历

    前天面试遇到一个多叉树面试的题目,在这里分享记录一下. 题目:一个树形的数据(如下数据),面试官给你一个id,然后拿到对应的name? 数据结构大概是这个样子 var cityData = [ { i ...

  2. hdfs对文件的增删改查

    源代码: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  3. 将word文件转为excel文件

    有些word文件里的数据是有顺序或者规律,想转成表格的形式,下面就以我要转的word为例. 我的word文件是这样的 1.word转txt(文本文件) 文件--->另存为--->路径--- ...

  4. java中“类”和“对象”到底有什么联系

    4.object和Class配合工作原理    [新手可忽略不影响继续学习] Class是"类"的意思,是抽象的,并没有具体的说是哪个东西.而object是具体的,实实在在存在的一 ...

  5. 将本地项目上传到gitLab操作

    在设置好SSH之后,执行下面的操作即可完成: git init    //  初始化git status  //查看提交文件状态git remote add origin git地址   //  连接 ...

  6. 什么是机器学习的特征工程?【数据集特征抽取(字典,文本TF-Idf)、特征预处理(标准化,归一化)、特征降维(低方差,相关系数,PCA)】

    2.特征工程 2.1 数据集 2.1.1 可用数据集 Kaggle网址:https://www.kaggle.com/datasets UCI数据集网址: http://archive.ics.uci ...

  7. cat /proc/cpuinfo 讲解

    查看cpu信息有什么用呢,我们来看看到底有哪些用处:1.和云服务提供商核算成本,现在基本是cpu和内存的费用最大,硬盘大小几乎被忽略了2.我们写程序时候是会关注多核还是单核的,否则不能充分利用多线程等 ...

  8. [翻译] 使用 TensorFlow 进行分布式训练

    本文以两篇官方文档为基础来学习TensorFlow如何进行分布式训练,借此进入Strategy世界.

  9. POP3协议(电子邮件邮局协议)中UIDL和TOP命令在实际使用中的作用

    POP3是电子邮件协议中用于接收邮件的协议,相较于发送邮件的SMTP协议,POP3的命令要多一些.主要的命令有LIST.STAT.RETR.DELE.UIDL.TOP.QUIT,以及用于登录邮箱的US ...

  10. golang内存对齐分析(转载)

    问题 type Part1 struct { a bool b int32 c int8 d int64 e byte } 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? func m ...