1、术语解释
-
Rule:一条规则可以看作是if else 一组判断和一组输出
-
RuleBase: RuleBase包含一个或多个规则包,它们已经被校验和编译完成,是可以序列化的
-
Package: 规则包,是规则以及其它相关结构的一个集合,包必须有一个名称空间,并且使用标准的java约定进行命名
-
WorkingMemory: 用户工作区,包含用户的数据和相关Rule的引用
-
Facts: Facts就是规则中用到的输入,Facts可以是任何规则可以存取的Java对象,规则引擎完全不会克隆对象,它仅仅是保存对对象的一个引用/指针
2、规则文件详解
目前市面上常用的drools规则文件通常是以 .drl 扩展名结尾
在一个drl文件中可以包含多个规则,函数等等。
规则文件的构成:
package package-name //定义包名
imports //导入java包
globals //定义全局变量,如 global java.util.List myGlobalList
functions //定义函数
rules //一系列的规则
querys //一系列查询
规则的构成:
package "packageName"
imports com.xxx.Xxx
rule "ruleName"
attributes
when
LHS
then
RHS
end
查询的构成
query "queryName"
LHS
end
说明:
LHS是规则的条件部分,可以定义变量
RHS是允许Java语义代码,RHS中的多条语句实质上是一个规则,只有满足全部语句才符合规则
任何在LHS中绑定的变量可以在RHS中使用
3、规则文件示例解读
package helloworld
import io.springboot.drools.model.Employee
rule "rule_employee_raise"
agenda-group "group-rule2"
no-loop true
when
$employee:Employee(year >= 3 && salary <= 10000)
then
System.out.println("抠门公司准备给员工ID="+$employee.getId()+" ,名字= "+$employee.getName()+" 加薪");
$employee.setSalary($employee.getSalary() + 100);
update($employee);
end
以上规则文件drl 可以看出 符合我们的规则构成
其中 :
attributes 为以下内容
agenda-group "name"
no-loop true
LHS条件部分
当传入的员工对象 $employee 的工作年限year 大于等于3年 并且 工资salary小于等于10000时 触发我们的规则
$employee:Employee(year >= 3 && salary <= 10000)
RHS部分可以执行相应的动作
满足条件的员工可以增加薪水100
其中 update($employee)
的作用是更新工作内存中的数据,并让相关的规则重新匹配。 (要避免死循环)
所以再attributes中 添加了 no-loop true
如果员工的工资原来为8000 执行了这个规则 没有添加 no-loop true
那么会导致循环加薪直到 工资变成10100
这是老板不想看到的
$employee.setSalary($employee.getSalary() + 100);
update($employee);
划重点:
规则引擎完全不会克隆对象,它仅仅是保存对对象的一个引用/指针
即,在规则定义中对fact的修改,就是对代码中fact对象的修改。
也即,规则的根本目的是产生一个供使用的输出结果,即修改后的JavaBean
相关代码
Springboot整合规则引擎Drools + redis