概念介绍
Drools规则引擎是对于各种情况的条件进行灵活匹配,从而根据条件返回各种各样的参数。规则匹配的方法分为两种,一种是在项目中硬编码的方式,一种是通过读取符合语法的excel表格。
硬编码语法
package
必须的选项,且放在编码的第一行,代表一种逻辑的区分,不必和真实的物理环境对应
import
与java的import作用及语法相同,导入规则所需要的类,在规则判断中用($对象名)获取导入的对象
rule部分
rule分为三部分,规则基本属性(规则名,执行顺序,规则生效时间,过期时间等)、条件部分(when)、结果部分(then)
基本属性部分
salience:数值越大越先执行
条件部分
when:取参数是用($参数名)形式获取,对传输过来的数据进行判断
结果部分
then ... end
如果符合了条件则执行then中的命令。
如下所示
package com.bonc.campaign;
//generated from Decision Table
import java.util.HashMap;
// rule values at B10, header at B5
rule "2678_yk_1"
salience 65526
when
$map:java.util.HashMap($map.get('age') ==10 || $map.get('age') ==20 , $map.get('age') >10, $map.get('money') <= 5)
then
$map.put('ruleType',"S");
end
rule "name"
salience number
when
...
then
...
end
when中“,”表示and
决策表形式
决策表形式更加直观,在解析时是由官方API把excel决策表解析成了硬编码。Excel表格形式如下
![](https://img-blog.csdnimg.cn/2021032116212752.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg0NTIyNw==,size_16,color_FFFFFF,t_70)
Ruleset对应package,Sequential代表根据排序进行优先级判断,CONDITION为条件,ACTION为结果
excel由API转化为硬编码如下
package com.gzf;
//generated from Decision Table
import java.util.HashMap;
// rule values at B10, header at B5
rule "14698_dn_1"
salience 65526
when
$map:java.util.HashMap($map.get('age') < 20, $map.get('book') > 100)
then
$map.put('type','S');
end
// rule values at B11, header at B5
rule "14698_dn_2"
salience 65525
when
$map:java.util.HashMap($map.get('age') < 40, $map.get('book') > 100)
then
$map.put('type','A');
$map.put('TEST','TEST');
end
实际案例
maven依赖
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>6.4.0.Final</version>
<!--<scope>import</scope>-->
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>6.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>6.4.0.Final</version>
</dependency>
<!--添加依赖-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>6.4.0.Final</version>
</dependency>
java类
package com.pson.drools;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.drools.core.impl.KnowledgeBaseImpl;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TestDrools {
public static void main(String[] args) {
System.out.println(TestDrools.class.getResource("").getPath());
HashMap map = new HashMap();
map.put("name", "gzf");
map.put("money", 0);
map.put("age", 30);
map.put("book", 300);
// 1、读取决策表进行规则过滤
// File file = new File("F:\\IDEAWorkspeace\\testjaranddrools\\src\\main\\resources\\make.xlsx");
// System.out.println(file.getPath());
// KieSession kieSession =getDrlStringByXLS(file,InputType.XLS);
// 2、硬编码方式进行规则过滤
KieSession kieSession = getDrlStringByDRL();
kieSession.insert(map);
kieSession.fireAllRules();
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
System.out.println("key:" + entry.getKey() + " value:" + entry.getValue() + ";");
}
}
private static KieSession getDrlStringByDRL() {
Resource resource = ResourceFactory.newReaderResource(new StringReader("" +
"package com.gzf;\n" +
"//generated from Decision Table\n" +
"import java.util.HashMap;\n" +
"\n" +
"rule \"14738_vz_1\"\n" +
"\tsalience 65526\n" +
"\twhen\n" +
"\t\t$map:java.util.HashMap($map.get('age') ==10 || $map.get('age') ==20 , $map.get('age') >10, $map.get('money') <= 5)\n" +
"\tthen\n" +
"\t\t$map.put('ruleType','test');\n" +
"end"+"\n" +
"rule \"14738_vz_2\"\n" +
"\tsalience 65527\n" +
"\twhen\n" +
"\t\t$map:java.util.HashMap($map.get('age') ==20 || $map.get('age') ==40 , $map.get('age') >10, $map.get('money') <= 5)\n" +
"\tthen\n" +
"\t\t$map.put('Type','A');\n" +
"end"));
KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
//加载规则流
knowledgeBuilder.add(resource, ResourceType.DRL);
knowledgeBuilder.getErrors().forEach(e -> {
System.out.println(e.getMessage());
});
KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
return knowledgeBase.newStatefulKnowledgeSession();
}
private static KieSession getDrlStringByXLS(File file, InputType inputType) {
try {
// String path = TestDrools.class.getResource("/").getPath();
File excelFile = file;
// File excelFile = new File(path+"决策表.xlsx");
Workbook workbookReadLead = new XSSFWorkbook(new FileInputStream(excelFile));
Sheet sheet = workbookReadLead.getSheetAt(0);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(new FileInputStream(excelFile), inputType);
System.out.println(drl);
KieHelper helper = new KieHelper();
helper.addContent(drl, ResourceType.DRL);
KnowledgeBaseImpl knowledgeBase = (KnowledgeBaseImpl) helper.build();
return knowledgeBase.newStatefulKnowledgeSession();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
但是如何在excel表格中实现参数不同、条件不同的条件过滤,自己还没研究,如果有知道的,恳请指教