Drool规则引擎入门
源码地址
https://gitee.com/ergo9527/drool-demo.git
工作流程
引擎启动后,首先进行编译工作,就是把我们定义好的rule加载到Production memory中,我们也可以把这个过程称为"构建知识库(knowledgeBuilder)";当我们的业务系统生成新的数据并传入到引擎,引擎把这些数据作为fact存储进Working memory;接着引擎开始"模式匹配(pattern matching)"工作,即对Working memory中的fact,匹配rule的condition项,如果匹配了,那么把这个rule加入到Agenda里面;最后是真正的执行操作,引擎会对Agenda里的rule按照优先级进行序列安排,然后执行rule定义好的action操作![img](Drool规则引擎手册
Drool入门Demo1.0
1.引入相关依赖
<!-- Drools -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.32.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.32.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.32.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>7.32.0.Final</version>
</dependency>
2.创建实体类
bean对象在规则引擎中就是Fact,用于去匹配规则的condition
@Data
@Builder
public class Account {
/**
* 开户人
*/
private String name;
/**
* 账户余额 单位:万元
*/
private Double money;
/**
* 账户类型:
* 黑卡: [100-∞)万
* 钻卡: [50-100)万
* 金卡: [10-50)万
* 普卡: [0-10)万
*/
private String accountType;
3.编写规则文件
在resources下创建一个rules文件夹用于放规则文件,规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件。
示例代码
package drools.demos.rules.ruledemo1
import com.lx.entity.Account
/*普卡账户判断*/
rule "account-rating-normal"
when
account: Account(money>=0,money<10)
then
account.setAccountType("普卡");
System.out.println("【"+account.getName()+"】为【"+account.getAccountType()+"】用户,当前可用余额为: "+account.getMoney()+" 万元");
System.out.println("=====存入10万元=====");
account.setMoney(account.getMoney()+10.0);
update(account);
end
/*金卡账户判断*/
rule "account-rating-gold"
when
account: Account(money>=10,money<50)
then
account.setAccountType("金卡");
System.out.println("【"+account.getName()+"】为【"+account.getAccountType()+"】用户,当前可用余额为: "+account.getMoney()+" 万元");
System.out.println("=====存入50万元=====");
account.setMoney(account.getMoney()+50.0);
update(account);
end
/*钻卡账户判断*/
rule "account-rating-diamond"
when
account: Account(money>=50,money<100)
then
account.setAccountType("钻卡");
System.out.println("【"+account.getName()+"】为【"+account.getAccountType()+"】用户,当前可用余额为: "+account.getMoney()+" 万元");
System.out.println("=====存入50万元=====");
account.setMoney(account.getMoney()+50.0);
update(account);
end
/*黑卡账户判断*/
rule "account-rating-black"
no-loop true
when
account: Account(money>=100)
then
account.setAccountType("黑卡");
System.out.println("【"+account.getName()+"】为【"+account.getAccountType()+"】用户,当前可用余额为: "+account.getMoney()+" 万元");
System.out.println("=====存入50万元=====");
account.setMoney(account.getMoney()+50.0);
update(account)
end
4.编写配置文件
在resources下创建一个META-INF(命名固定)文件夹用于放配置文件
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="rules1" packages="drools.demos.rules.ruledemo1">
<ksession name="ruledemo1"/>
</kbase>
</kmodule>
kbase结点用于配置规则库或知识库的信息,这里我们指定了一个指向drools.demos.rules.ruledemo1的名为rules1的kbase结点,意思就是这个rules1结点将使用我们在ruledemo1.drl里定义好的规则(ruledemo1.drl里定义的package名就是drools.demos.rules.ruledemo1)来构建知识库;kbase结点下又配置了一个名为ruledemo1的ksession结点,ksession代表了运行时的执行会话,可以在一个kbase下指定多个不同参数的session
5.编写主函数
public class Application {
public static void main(String[] args) {
KieServices ks = KieServices.Factory.get();
KieContainer kieContainer = ks.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("ruledemo1");//就是kmodule.xml里定义的那个ksession
Account account = Account.builder().name("刘二狗").accountType("").money(9.90).build();
kieSession.insert(account);//把这个Fact传入
kieSession.fireAllRules();//开始规则检验
}
6.运行并观察结果
【刘二狗】为【普卡】用户,当前可用余额为: 9.9 万元
=====存入10万元=====
【刘二狗】为【金卡】用户,当前可用余额为: 19.9 万元
=====存入50万元=====
【刘二狗】为【钻卡】用户,当前可用余额为: 69.9 万元
=====存入50万元=====
【刘二狗】为【黑卡】用户,当前可用余额为: 119.9 万元
=====存入50万元=====