Drools 使用 Excel 文件中的规则
1. 概述
Drools 支持以电子表格格式管理业务规则。
在本文中,我们将看到一个使用 Drools 通过 Excel 文件管理业务规则的快速示例。
2. Maven依赖
让我们将所需的 Drools 依赖项添加到我们的应用程序中:
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>7.1.0.Beta2</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.1.0.Beta2</version>
</dependency>
这些依赖项的最新版本可以在kie-ci 和drools-decisiontables 中找到。
3. 在 Excel 中定义规则
对于我们的示例,让我们定义规则以根据客户类型和客户年数确定折扣:
- 3年以上的个人客户享受15%的折扣
- 3年以下的个人客户享受5%的折扣
- 所有商务客户均可享受 20% 的折扣
3.1. Excel 文件
对于我们的简单示例,我们使用了最相关的一组关键字:
- RuleSet – 表示决策表的开始
- Import – 规则中使用的 Java 类
- RuleTable – 表示规则集的开始
- Name - 规则的名称
- CONDITION – 要根据输入数据检查的条件的代码片段。规则应至少包含一个条件
- ACTION – 满足规则条件时要执行的操作的代码片段。规则应至少包含一项操作。在示例中,我们在Customer对象上调用setDiscount
此外,我们在 Excel 文件中使用了Customer类。所以,让我们现在创建它。
3.2. Customer类
从 Excel 表中的 CONDITIONs 和 ACTION 可以看出,我们使用Customer类的对象作为输入数据(type和years)并存储结果(discount)。
Customer类:
public class Customer {
private CustomerType type;
private int years;
private int discount;
// Standard getters and setters
public enum CustomerType {
INDIVIDUAL,
BUSINESS;
}
}
4. 创建 Drools 规则引擎实例
在我们可以执行我们定义的规则之前,我们必须使用 Drools 规则引擎的一个实例。为此,我们必须使用 Kie 核心组件。
4.1. KieServices
KieServices类提供对所有 Kie 构建和运行时设施的访问。它提供了几种工厂、服务和实用方法。所以,让我们首先获取一个KieServices实例:
KieServices kieServices = KieServices.Factory.get();
使用 KieServices,我们将创建KieFileSystem、KieBuilder和KieContainer的新实例。
4.2. KieFileSystem
KieFileSystem是一个虚拟文件系统。让我们将 Excel 电子表格添加到其中:
Resource dt
= ResourceFactory
.newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
getClass());
KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(dt);
4.3. KieBuilder
现在,通过将KieFileSystem的内容传递给KieBuilder来构建它:
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
如果成功构建,它会创建一个KieModule (任何 Maven 生成的带有 kmodule.xml 的 jar 都是KieModule)。
4.4. KieRepository
该框架自动将KieModule(由构建产生)添加到KieRepository:
KieRepository kieRepository = kieServices.getRepository();
4.5. KieContainer
现在可以使用这个KieModule使用它的ReleaseId创建一个新的KieContainer。在这种情况下,Kie 分配了一个默认的ReleaseId:
ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId();
KieContainer kieContainer
= kieServices.newKieContainer(krDefaultReleaseId);
4.6. KieSession
我们现在可以从KieContainer获取KieSession。我们的应用程序与KieSession交互,它存储和执行运行时数据:
KieSession kieSession = kieContainer.newKieSession();
5. 执行规则
最后,是时候提供输入数据并触发规则了:
Customer customer = new Customer(CustomerType.BUSINESS, 2);
kieSession.insert(customer);
kieSession.fireAllRules();
6. 测试用例
现在让我们添加一些测试用例:
public class DiscountExcelIntegrationTest {
private KieSession kSession;
@Before
public void setup() {
Resource dt
= ResourceFactory
.newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
getClass());
kSession = new DroolsBeanFactory().getKieSession(dt);
}
@Test
public void
giveIndvidualLongStanding_whenFireRule_thenCorrectDiscount()
throws Exception {
Customer customer = new Customer(CustomerType.INDIVIDUAL, 5);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 15);
}
@Test
public void
giveIndvidualRecent_whenFireRule_thenCorrectDiscount()
throws Exception {
Customer customer = new Customer(CustomerType.INDIVIDUAL, 1);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 5);
}
@Test
public void
giveBusinessAny_whenFireRule_thenCorrectDiscount()
throws Exception {
Customer customer = new Customer(CustomerType.BUSINESS, 0);
kSession.insert(customer);
kSession.fireAllRules();
assertEquals(customer.getDiscount(), 20);
}
}
7. 故障排除
Drools 将决策表转换为DRL 。因此,处理 Excel 文件中的错误和拼写错误可能很困难。错误通常与 DRL 的内容有关。因此,要进行故障排除,打印和分析 DRL 会有所帮助:
Resource dt
= ResourceFactory
.newClassPathResource("com/blogdemo/drools/rules/Discount.xls",
getClass());
DecisionTableProviderImpl decisionTableProvider
= new DecisionTableProviderImpl();
String drl = decisionTableProvider.loadFromResource(dt, null);