Drools是一个开源的业务规则管理系统(BRMS)和规则引擎,它允许开发者以接近自然语言的形式定义业务规则,并将这些规则应用到应用程序中,实现业务逻辑的自动化和决策过程的优化。Drools基于Java语言开发,使用Rete算法来评估业务规则,并且支持声明方式表达业务逻辑。它允许使用非XML的本地语言编写规则,便于学习和理解,同时也可以嵌入Java代码到规则文件中,使得学习Drools更加吸引人。(简而言之:突然该业务了,不用修改源码,而是修改规则文件)
使用Drools需要了解KIE。Drools与KIE的关系可以这样理解:Drools是KIE生态中的一个关键组件,专注于业务规则的管理,而KIE提供了一个更广泛的平台,包括Drools在内的多个组件,以支持业务规则、流程、决策和规划等多种业务场景。 通过KIE,Drools和其他组件可以共享通用的API,如KieServices、KieContainer、KieSession等,这些API使得在不同的项目中使用这些组件变得更加一致和方便。 总的来说,Drools是KIE项目中的一个子集,而KIE提供了一个更大的框架来整合和管理Drools以及其他组件。(简而言之:Drools是KIE下的一个模块,为了KIE下模块更好的配合工作,KIE提供了统一组件来实现模块的使用和模块之间的调用,即KieServices、KieContainer、KieBase等组件。而此文章只单独使用Drools,不用调用其他模块)
Drools执行流程如下:
看代码:
一、maven引入包:看情况挑选复制
//drools-core:这是Drools规则引擎的核心包,包含了Drools规则引擎的基本功能,如规则存储、规则执行等核心机制
<dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId><version>7.59.0.Final</version></dependency>//drools-compiler:这个包提供了对Drools规则文件(如DRL文件)的编译功能,将规则文件编译成可以在运行时执行的规则<dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.59.0.Final</version></dependency>
//drools-decisiontables:支持从Excel或CSV文件中加载规则,这些文件通常被称为决策表,它们提供了一种直观的方式来定义复杂的业务规则<dependency><groupId>org.drools</groupId><artifactId>drools-decisiontables</artifactId><version>7.59.0.Final</version></dependency>
//kie-api:提供了Kie工作流和规则引擎的API,它是基于Drools的Kie项目的一部分,用于构建更加复杂的业务逻辑和工作流<dependency><groupId>org.kie</groupId><artifactId>kie-api</artifactId><version>7.59.0.Final</version></dependency>//还有其他包:例如:drools-templates:提供了模板功能,允许用户使用模板来生成规则,这可以简化规则的创建和维护过程。
//drools-mvel:Drools所需的脚本语言包,MVEL(MVFLEX Expression Language)是一个动态的表达式语言,用于在Drools规则中编写更复杂的逻辑。
二:建立规则文件目录和kmodule.xml文件
1:kmodule.xml
<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule"><!--name:指定kbase的名称,可以任意,但是需要唯一packages:指定规则文件的目录,需要根据实际情况填写,否则无法加载到规则文件default:指定当前kbase是否为默认--><kbase name="myKbase1" packages="rules" default="true"><!--name:指定ksession名称,可以任意,但是需要唯一default:指定当前session是否为默认--><ksession name="ksession-rule" default="true"/></kbase>
</kmodule>
关于kmoudle.xml文件,有内容需要学习:
在Drools规则引擎中,`KieBase` 和 `KieSession` 是两个核心概念,它们分别代表了知识库和知识会话,用于管理和执行业务规则。下面是它们各自的功能和用途:
### KieBase(知识库)
`KieBase` 是一个包含一组规则、流程、类和函数的容器。它相当于一个编译后的规则集合,其中包含了所有的业务逻辑和知识。`KieBase` 本身不包含任何运行时数据,它更像是一个静态的知识库,包含了所有的规则定义和相关的元数据。以下是 `KieBase` 的一些关键点:1. **规则存储**:`KieBase` 存储了所有的规则定义,这些规则定义可以是DRL文件(Drools规则语言)或决策表。
2. **模块化**:`KieBase` 允许模块化设计,不同的 `KieBase` 可以包含不同的规则集合,这有助于大型项目的模块化和扩展。
3. **版本控制**:`KieBase` 可以包含多个版本的规则,这有助于管理规则的版本和变更。
4. **性能优化**:`KieBase` 可以被编译和优化,以提高规则执行的性能。
5. **多态性**:`KieBase` 支持多态性,允许在不同的上下文中使用相同的规则。
### KieSession(知识会话)
`KieSession` 是 `KieBase` 的一个实例,它包含了运行时的数据和状态。`KieSession` 用于执行 `KieBase` 中定义的规则。以下是 `KieSession` 的一些关键点:1. **规则执行**:`KieSession` 用于执行 `KieBase` 中的规则。它接收事实(facts),并根据这些事实触发相应的规则。
2. **状态管理**:`KieSession` 管理着会话的状态,包括插入、修改和删除事实。
3. **事务管理**:`KieSession` 提供了事务管理功能,确保规则执行的一致性和完整性。
4. **类型安全**:`KieSession` 支持类型安全,可以确保只有正确的事实类型被插入到会话中。
5. **多种类型**:Drools 提供了不同类型的 `KieSession`,如 `StatefulKnowledgeSession` 和 `StatelessKnowledgeSession`。`StatefulKnowledgeSession` 保持状态,适用于需要长期运行的应用程序,而 `StatelessKnowledgeSession` 不保持状态,适用于一次性的规则评估。
6. **并发执行**:`KieSession` 支持并发执行,可以在多线程环境中使用。
7. **规则流**:在某些类型的 `KieSession` 中,如 `ProcessKieSession`,可以执行业务流程。
简而言之,`KieBase` 是规则和知识的静态存储,而 `KieSession` 是这些规则和知识的动态执行环境。通过 `KieBase` 和 `KieSession`,Drools 提供了一个强大的框架来定义、管理和执行复杂的业务规则。
2:规则文件
package rules
import com.drools.Order//规则一:所购图书总价在100元以下的没有优惠
rule "ninee"when$order:Order(originalPrice < 100)then$order.setRealPrice($order.getOriginalPrice());System.out.println("成功匹配到规则一:所购图书总价在100元以下的没有优惠");
end
//规则文件书写规范
package //规则文件包名
import //java实体类
function // Optional
query // Optional
declare // Optional
global // Optional
rule "rule name"
// Attributes
when
// Conditions 条件,若符合,则执行then里面的
then
// Actions 执行代码
endrule "rule2 name"
......
三、具体的执行代码
1:创建实体类
import lombok.*;@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Order {private Double originalPrice; //初始价格private Double realPrice;//实际价格}
2:具体计算方法
KieServices kieServices = KieServices.Factory.get();KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();//会话对象,用于和规则引擎交互KieSession kieSession = kieClasspathContainer.newKieSession();//构造订单对象,设置原始价格,由规则引擎根据优惠规则计算优惠后的价格Order order = new Order();order.setOriginalPrice(210D);//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配kieSession.insert(order);//激活规则引擎,如果规则匹配成功则执行规则kieSession.fireAllRules();//关闭会话kieSession.dispose();System.out.println("优惠前原始价格:" + order.getOriginalPrice() +",优惠后价格:" + order.getRealPrice());
四、执行代码结果
以上就能实现规则文件的读取和规则结果的计算。但是既然集成到了若依里面,最好将规则存储到数据库,所有规则从数据库读取,这样更方便通过网页维护,而非编写规则文件。
那么需要修改计算方法
String myRule = "package rules\n" +"import com.s3.drools.Order\n" +"dialect \"mvel\"\n" +"\n" +"rule \"ninee\"\n" +" when\n" +" $order:Order(originalPrice < 100)\n" +" then\n" +" $order.setRealPrice($order.getOriginalPrice());\n" +" System.out.println(\"成功匹配到规则一:所购图书总价在100元以下的没有优惠\");\n" +"end\n";KieHelper helper = new KieHelper();helper.addContent(myRule, ResourceType.DRL);KieSession ksession = helper.build().newKieSession();Order ordera = new Order();ordera.setOriginalPrice(210D);//将数据提供给规则引擎,规则引擎会根据提供的数据进行规则匹配ksession.insert(ordera);ksession.fireAllRules();ksession.dispose();System.out.println("优惠前原始价格:" + ordera.getOriginalPrice() +",优惠后价格:" + ordera.getRealPrice());
以上 myrule即为规则,那么就可以存储到数据库了。