目录
简介
drools规则引擎,官网地址:Drools - Drools - Business Rules Management System (Java™, Open Source)
可以通过配置或低代码的形式借助规则引擎实现规则、以及程序运行逻辑的动态配置和修改
使用场景
以下五种情况是考虑是否使用规则引擎、是否使用Drools规则引擎的考虑因素:
1、只有少量静态规则,并且不经常改变,不建议使用规则引擎;
2、需要在运行时动态修改规则,可考虑使用规则引擎;
3、在应用程序中需要通过可视化工具来修改规则,可考虑使用规则引擎;
4、规则需要非技术人员维护的情况下,可考虑使用规则引擎;
5、如果项目工期较紧,除非非常熟悉规则引擎,否则不建议使用;
6、如果使用Excel来管理规则,可考虑使用规则引擎;
语法和结构
大致结构
package 包路径
// import 引入使用的依赖
// 定义全局变量
rule "rule_name1"
// Attribute 属性
// Attribute
when
// Conditions 条件
then
// Actions 执行
end
rule "rule_name2"
// Attribute 属性
// Attribute
when
// Conditions 条件
then
// Actions 执行
end
rule "rule_name3"
// Attribute 属性
// Attribute
when
// Conditions 条件
then
// Actions 执行
end
Attribute常见属性介绍
规则属性 | 解释 | 举例 |
salience | 定义规则优先级,是一个整数。当在激活队列中排序时,salience的值越大,优先级越高。 | salience 99 |
enabled | 定义规则是否启用. true 启用,false 禁用,默认值是true | enabled true |
date-effective | 包含时间和日期的字符串,当当前时间大于date-effective时,该规则才会被激活。这个时间格式可以修改,见下方具体的用法 | date-effective “4-5月-2022” |
date-expires | 设置规则的过期时间,时间格式和上方一样。 | date-expires “4-5月-2022” |
no-loop | 布尔值,默认值为false, 定义当当前规则规则的结果修改了fact对象时,是否可以再次执行该规则。true:不可以, false:可以,可能会导致死循环。指的是当前规则的修改,如果别的规则修改了,还会导致该规则的触发 | no-loop true |
agenda-group | Agenda groups允许您对agenda进行分区,以提供对规则组的更多执行控制。 只有获得焦点的议程组中的规则才能被激活。 ,但是这个里面有个特例,如果某个规则没有配置 agenda-group,但是它模式匹配成功了,那么会被分到默认的组(main),这个main组的规则也会执行。 | agenda-group “GroupName” |
auto-focus | 布尔值,仅适用于Agenda-Group内的规则。当值为true时,下次激活该规则时,会将焦点自动给这个Agenda group | auto-focus true |
activation-group | 表示该组下的规则只有一个规则会被执行,该组下其余激活的规则会被取消执行。 但是别的组激活的规则可能会被执行。 | activation-group “GroupName” |
duration | long类型的值,如果在这个时间之后规则还成立,那么执行该规则 | duration 1000 |
timer | 一个字符串,标识用于调度规则的 int(间隔)或 cron 计时器定义。 | Example: timer ( cron:* 0/15 * * * ? ) (every 15 minutes) |
calendar | 定义Quartz calendar用于调度规则。 | |
lock-on-active | 一个布尔值,仅适用于规则流组或议程组中的规则。 选择该选项后,下次规则的规则流组变为活动状态或规则的议程组获得焦点时,规则无法再次激活,直到规则流组不再处于活动状态或议程组失去焦点。 这是 no-loop 属性的更强版本,因为匹配规则的激活被丢弃,无论更新的来源如何(不仅是规则本身)。 此属性非常适合计算规则,其中您有许多修改事实的规则并且您不希望任何规则重新匹配和再次触发。 | lock-on-active true |
dialect | 将 JAVA 或 MVEL 标识为用于规则中的代码表达式的语言的字符串。 默认情况下,该规则使用在包级别指定的方言。 此处指定的任何方言都会覆盖该规则的包方言设置。 | dialect “JAVA” |
when和then语法介绍
简单使用
rule "rule1"
when
Person(car.name == "宝马")
then
System.out.println("匹配成功");
end
解释:Person(car.name == "宝马") 匹配到此规则需符合条件:1入参类型必须为Person,2其中car.name必须等于宝马才会匹配成功 “rule1”规则
进阶使用
package myrule
import java.util.Map;
import java.util.HashMap;
import org.common.utils.StringUtils;
global java.lang.StringBuilder logResultInfo;
global java.util.HashMap resultMap;
rule "规则名称"
when
$map: HashMap()
if((( !StringUtils.isEmpty($map.get("slqfzsl")) ) && ( (Double.valueOf($map.get("slqfzsl").toString())) >= 12 )))do[if]
else do[then]
then
then[if]
resultMap.put("1123598818738675223,gfzg", ("11") );
resultMap.put("then-log-if","执行宁波限购区购房资格/购房资格(gfzg)=11\n");
then[then]
resultMap.put("1123598818738675223,gfzg", ("是") );
resultMap.put("then-log-then","执行宁波限购区购房资格/购房资格(gfzg)=是\n");
resultMap.put("1123598818738675223,gender", ("12") );
resultMap.put("then-log-then","执行宁波限购区购房资格/性别(gender)=12\n");
end
解释:使用if else
$map: HashMap() 入参为map则匹配成功
if((( !StringUtils.isEmpty($map.get("slqfzsl")) ) && ( (Double.valueOf($map.get("slqfzsl").toString())) >= 12 )))do[if] 符合条件执行then[if]
else do[then] 否则执行then[then] (其中 中括号中的可以自己命名)
import 引入相关需要使用到的java类
global 定义全局变量
启动运行drools代码
// 设置日期格式,否则可能会报错(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
// 创建kieSession
KieSession kieSession = kieContainer.newKieSession(kieBaseName + "-session");
// 添加监听器,便于观察日志
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
// kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
// 设置全局参数
kieSession.setGlobal("logResultInfo", logResultInfo);
// then返回值
Map<String,Object> resultMap = new HashMap<>();
kieSession.setGlobal("resultMap", resultMap);
// 将customerOrder对象加入到工作内存中
kieSession.insert(param);
// 触发所有的规则,如果只想触发指定的规则,则使用fireAllRules(AgendaFilter agendaFilter)方法
kieSession.fireAllRules();
kieSession.dispose();
pom依赖
<!--drools-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>${drools.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>