Drools 规则引擎实战:原理、规则语法、数据库动态规则与企业级玩法

Drools 规则引擎实战:原理、规则语法、数据库动态规则与企业级玩法

什么是 Drools

Drools 是一个基于 Java 的规则引擎(Rule Engine)。

它的核心目标:

text 复制代码
将业务规则从 Java 代码中解耦出来。

例如:

传统代码:

java 复制代码
if(orderAmount > 1000 && vip){
    discount += 200;
}

随着业务增长:

  • VIP规则
  • 新人规则
  • 节日活动
  • 门店活动
  • 满减
  • 风控
  • 审核

最终会形成:

text 复制代码
if else 地狱

Drools 的核心思想:

text 复制代码
业务规则 ≠ Java代码

而是:

text 复制代码
规则 = 可动态配置的业务决策

Drools 的核心能力

Drools 最强的地方不是:

text 复制代码
if 判断

而是:

规则推理

例如:

text 复制代码
规则A:
VIP用户增加200优惠

规则B:
新人增加50优惠

规则C:
优惠超过300需要审核

规则 C 并不知道:

  • 优惠来自 VIP
  • 还是来自 新人
  • 还是来自 活动

它只关心:

text 复制代码
最终事实

这就是:

基于事实(Fact)的推理


Drools 核心概念

概念 说明
Fact 事实对象(Java Bean)
Rule 规则
Working Memory 工作内存
KieSession 规则运行会话
Agenda 待执行规则队列
Rete Network 底层推理网络

Drools 工作流程

第一步:插入事实对象

java 复制代码
session.insert(order);
session.insert(user);
session.insert(result);

这些对象:

会进入:

Working Memory


第二步:规则匹配

Drools 会自动匹配:

drools 复制代码
Order(amount > 1000)
User(vip == true)

第三步:触发规则

drools 复制代码
then
    $r.addDiscount(200);

第四步:规则联动

另一个规则:

drools 复制代码
DecisionResult(totalDiscount > 300)

会再次自动触发。


Drools 规则语法(DRL)

Drools 使用:

text 复制代码
.drl

规则文件。


一个完整规则

drools 复制代码
package rules

import com.demo.Order
import com.demo.User
import com.demo.DecisionResult

rule "vip discount"

when

    Order(amount > 1000)

    User(vip == true)

    $r : DecisionResult()

then

    $r.addDiscount(200);

    System.out.println("触发VIP优惠");

end

DRL 语法结构

语法 说明
package 包名
import 导入Java类
rule 规则名称
when 条件
then 动作
end 规则结束

条件部分(when)

例如:

drools 复制代码
Order(amount > 1000)

等价于:

java 复制代码
order.getAmount() > 1000

多条件

drools 复制代码
Order(amount > 1000)

User(vip == true)

表示:

text 复制代码
同时满足

变量绑定

drools 复制代码
$r : DecisionResult()

表示:

text 复制代码
把 DecisionResult 绑定为变量 $r

后面:

drools 复制代码
$r.addDiscount(200);

即可直接调用。


then 动作部分

drools 复制代码
then
    $r.addDiscount(200);

本质:

是:

java 复制代码
result.addDiscount(200);

Drools:

底层仍然是 Java 对象操作。


一个完整营销规则示例

order.drl

drools 复制代码
package rules

import com.demo.Order
import com.demo.User
import com.demo.DecisionResult

rule "vip discount"
when
    Order(amount > 1000)

    User(vip == true)

    $r : DecisionResult()
then
    $r.addDiscount(200);

    System.out.println("触发:VIP优惠");
end


rule "new user discount"
when
    User(newUser == true)

    $r : DecisionResult()
then
    $r.addDiscount(50);

    System.out.println("触发:新人优惠");
end


rule "big order point"
when
    Order(amount > 5000)

    $r : DecisionResult()
then
    $r.addPoint(100);

    System.out.println("触发:大额积分");
end


rule "need audit"
when
    $r : DecisionResult(totalDiscount > 300)
then
    $r.setNeedAudit(true);

    System.out.println("触发:人工审核");
end

如何与数据库结合

企业里:

几乎不会把规则写死:

text 复制代码
rules/*.drl

因为:

运营会频繁修改规则。


数据库设计

rule_definition

sql 复制代码
CREATE TABLE rule_definition
(
    id            BIGINT PRIMARY KEY,
    rule_code     VARCHAR(50),
    rule_name     VARCHAR(200),
    drl_content   TEXT,
    status        INT,
    version_no    INT,
    tenant_id     BIGINT,
    add_date      DATETIME
);

数据库存储规则

drools 复制代码
rule "vip discount"

when
    Order(amount > 1000)

then
    ...
end

直接存:

text 复制代码
TEXT

即可。


动态加载规则

从数据库读取

java 复制代码
String drl = ruleMapper.getRuleContent("vip_rule");

动态编译

java 复制代码
KieServices ks = KieServices.Factory.get();

KieFileSystem kfs = ks.newKieFileSystem();

kfs.write(
    "src/main/resources/rules/vip.drl",
    drl
);

KieBuilder kb = ks.newKieBuilder(kfs);

kb.buildAll();

创建 KieSession

java 复制代码
KieContainer kc = ks.newKieContainer(
        ks.getRepository().getDefaultReleaseId()
);

KieSession session = kc.newKieSession();

执行规则

java 复制代码
session.insert(order);

session.insert(user);

session.insert(result);

session.fireAllRules();

常用高级语法

salience(优先级)

drools 复制代码
rule "vip"

salience 100

数字越大:

越先执行。


no-loop

防止死循环。

drools 复制代码
rule "test"

no-loop true

update()

更新事实对象。

drools 复制代码
update($r);

会重新触发规则匹配。


agenda-group

规则分组。

drools 复制代码
agenda-group "marketing"

企业使用中的真实问题

Drools:

虽然强大。

但:

也有很多问题。

  • 启动重
  • 内存占用高
  • 调试困难
  • 规则冲突难排查
  • 热更新复杂
  • 学习曲线高

ERP/收银系统中的最佳实践

真实企业:

通常:

核心交易逻辑

使用:

text 复制代码
Java硬编码

保证:

  • 性能
  • 稳定
  • 可控

动态营销规则

使用:

text 复制代码
Drools

保证:

  • 灵活
  • 动态配置
  • 运营可控
  • 热更新

总结

Drools 本质:

不是:

text 复制代码
替代 Java

而是:

在 Java 之上构建业务规则推理层

它真正的价值:

是:

业务规则动态化

以及:

规则自动联动推理

相关推荐
金融小白数据分析之路22 分钟前
绍兴市镇街echarts 制作
前端·数据库·echarts
桐薇全肯定28 分钟前
MySQL学生成绩管理系统实战操作
java·数据库·sql
爱昏羔30 分钟前
上篇:从PDF到向量库 — 物流行业RAG系统的知识库构建全解析
python·langchain·pdf·agent·rag
麻雀飞吧33 分钟前
最新量化实现难点,规则和流程要先有形状
人工智能·python
用户03321266636736 分钟前
使用 Python 在 Word 文档中添加或删除文本框
python
hellojike43 分钟前
free-stockdb本地金融数据库核心设计
数据库·金融
Nuanyt1 小时前
SSM 学习记录 第二部分 Spring整合Mybatis&Junit AOP核心概念 Spring事务管理 SpringMVC 请求与响应 Rest风格
java·spring·junit·mybatis·restful
醉城夜风~1 小时前
C++模板详解:从基础到高级全面解析
java·开发语言·c++
井川廊咏1 小时前
初探性能优化——2个月到4小时的性能提升
jvm·数据库·性能优化