规则引擎 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 65535
agenda-group "rule-group-001"
when
$account: Account(sex != "女")
then
list.add("性别不对");
end
// rule values at B12, header at B6
rule "ExcelTable_12"
salience 65534
agenda-group "rule-group-001"
when
$account: Account(age < 22 || age> 28)
then
list.add("年龄不合适");
end
// rule values at B13, header at B6
rule "ExcelTable_13"
salience 65533
agenda-group "rule-group-002"
when
$account: Account(balance < 1000)
then
list.add("工资太低");
end
Drools提供的将xls文件编译为drl格式字符串的API如下:
@DisplayName("Excel To Rule")
@Test
public 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;
}
@Override
public String toString() {
return "Account{" +
"accountno=" + accountno +
", balance=" + balance +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
测试类:
package com.ppl