如何在Drools决策表中配置区间校验规则 是否支持使用in关键字
Drools薪资区间匹配决策表实现方案
1 前置事实模型定义
先定义传入规则引擎的事实对象,承载输入薪资和输出等级字段:
public class SalaryFact { // 输入:待校验的薪资数值 private Number salary; // 输出:匹配到的薪资等级 private String grade; public SalaryFact() {} public SalaryFact(Number salary) {this.salary = salary;} // getter、setter public Number getSalary() {return salary;} public void setSalary(Number salary) {this.salary = salary;} public String getGrade() {return grade;} public void setGrade(String grade) {this.grade = grade;} }
2 区间匹配决策表设计
Drools支持XLS/XLSX/CSV格式的决策表,针对你提出的(0,10000)→Grade A、(10000,15000)→Grade B的映射规则,决策表核心配置如下(以Excel为例,对应单元格内容直接填写即可):
| 单元格位置 | 填写内容 | 作用说明 |
|---|---|---|
| A1 | package rules.salary | 定义规则所属包路径 |
| A2 | import com.example.SalaryFact | 导入自定义事实类 |
| A4 | RuleTable SalaryGradeMatch | 决策表起始标识,后续为规则集配置 |
| A5 | 规则名 | 规则属性列头 |
| B5 | CONDITION | 标记该列为条件列 |
| C5 | CONDITION | 标记该列为条件列 |
| D5 | ACTION | 标记该列为动作列 |
| A6 | 规则标识 | 规则名列说明 |
| B6 | $s:SalaryFact() | 绑定事实对象到变量$s |
| C6 | $s:SalaryFact() | 复用已绑定的事实对象 |
| D6 | $s.setGrade("$param"); | 定义等级赋值动作 |
| A7 | NAME | 标记该列为规则名参数位 |
| B7 | salary > $param | 定义薪资下限判断逻辑,$param读取同列下单元格值 |
| C7 | salary < $param | 定义薪资上限判断逻辑,$param读取同列下单元格值 |
| D7 | 输出等级 | 动作列说明 |
| A8 | rule_grade_a | 第一条规则名称 |
| B8 | 0 | Grade A对应薪资下限 |
| C8 | 10000 | Grade A对应薪资上限 |
| D8 | Grade A | 命中第一条规则后输出的等级 |
| A9 | rule_grade_b | 第二条规则名称 |
| B9 | 10000 | Grade B对应薪资下限 |
| C9 | 15000 | Grade B对应薪资上限 |
| D9 | Grade B | 命中第二条规则后输出的等级 |
边界调整提示:如果业务需要闭区间匹配(比如10000归为Grade A),只需要把对应条件的比较符调整为
>=/<=,同步错开相邻区间的边界值避免规则冲突即可。
3 关于in关键字是否适用于区间规则的说明
这类连续上下限的区间判断场景不适合用in关键字实现:
- Drools中的
in运算符仅支持离散枚举值匹配,比如salary in (5000, 10000, 15000)是合法语法,作用是判断薪资是否恰好等于括号内列出的某一个值 in不支持连续范围语法,无法直接表达“值大于下限且小于上限”的逻辑,如果强行用in实现区间匹配,需要枚举区间内所有可能的数值,完全没有可维护性- 连续区间场景直接使用
>、<、>=、<=等比较运算符组合判断是官方推荐的实现方式,在决策表中配置也最简洁。
4 规则触发效果
- 传入
SalaryFact(salary=8500),命中第一条规则,输出grade为Grade A - 传入
SalaryFact(salary=12000),命中第二条规则,输出grade为Grade B - 传入
SalaryFact(salary=10000),按照当前开区间配置,命中第二条规则,输出grade为Grade B
内容的提问来源于stack exchange,提问作者user1101
相关产品推荐
相关产品推荐

