一:简介
Drools规则文件支持.drl和.xls两种格式,并支持两种格式的文件互相转换,xls格式的文件(Excel)通常称为决策表(decision table),决策表是一个“精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。

二:语法
| 关键字 | 说明 | 是否必须 |
|---|---|---|
| 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;
//generated from Decision Table
import com.example.springbootdrools.entity.Person;
import java.util.List;
global java.util.List listRules;
// rule values at B10, header at B5
rule "personCheck_10"
salience 65535
agenda-group "sign"
when
$person : Person(sex != "男")
then
listRules.add("性别不对");
end
// rule values at B11, header at B5
rule "personCheck_11"
salience 65534
agenda-group "sign"
when
$person : Person(age < 22 || age > 25)
then
listRules.add("年龄不合适");
end
// rule values at B12, header at B5
rule "personCheck_12"
salience 65533
agenda-group "sign"
when
$person : Person(salary < 10000)
then
listRules.add("工资太低了");
end
三:集成
3.1 pom.xml
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.10.0.Final</version>
</dependency>
drools-decisiontables 已经集成了其它依赖,所以只需要引入这一个依赖就行了,drools-core、drools-compiler等不需要再引入。

3.2 entity
public class Person {
private String sex;
private int age;
private double salary;
}
3.3 util
package com.example.springbootdrools.util;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.utils.KieHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
public class KieSessionUtils {
private KieSessionUtils() {
}
// 把xls文件解析为String
public static String getDRL (String realPath) throws FileNotFoundException {
File file = new File(realPath);
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);
System.out.println(drl);
return drl;
}
// drl为含有内容的字符串
public static KieSession createKieSessionFromDRL(String drl) throws Exception{
KieHelper kieHelper = new KieHelper();
kieHelper.addContent(drl, ResourceType.DRL);
Results results = kieHelper.verify();
if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);
for (Message message : messages) {
System.out.println("Error: "+message.getText());
}
// throw new IllegalStateException("Compilation errors were found. Check the logs.");
}
return kieHelper.build().newKieSession();
}
// realPath为Excel文件绝对路径
public static KieSession getKieSessionFromXLS(String realPath) throws Exception {
return createKieSessionFromDRL(getDRL(realPath));
}
}
3.4 test
@RequestMapping("/test3")
public void test3() throws Exception {
String realPath = "/Users/xxx/Desktop/testRule.xls";
KieSession session = KieSessionUtils.getKieSessionFromXLS(realPath);
Person person = new Person();
person.setSex("男");
person.setAge(35);
person.setSalary(1000);
List<String> list = new ArrayList<String>();
session.setGlobal("listRules",list);
session.insert(person);
session.getAgenda().getAgendaGroup("sign").setFocus();
session.fireAllRules();
for (String s : list) {
System.out.println(s);
}
session.dispose();
}

1858

被折叠的 条评论
为什么被折叠?



