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 之上构建业务规则推理层

它真正的价值:

是:

业务规则动态化

以及:

规则自动联动推理

相关推荐
清风一徐9 小时前
Python文件处理
开发语言·python
承渊政道9 小时前
【MySQL数据库学习】(MySQL数据库基础)
数据库·学习·mysql·ubuntu·bash·数据库架构·数据库系统
0pen19 小时前
android-sqlite3:从官方 SQLite 源码自动构建 Android 可用的 sqlite3
android·数据库·sqlite
六月雨滴9 小时前
Oracle RMAN 恢复场景全解
数据库·oracle·dba
weixin_550083159 小时前
基于Python的豆瓣电影数据爬取与可视化分析
开发语言·python
Lenyiin9 小时前
第5篇_Python文件操作与异常处理:程序与外界交互的桥梁
python·oracle·交互
Hwang2529 小时前
Spring 框架 -01 -单例池的一些理解
java
AI人工智能+电脑小能手9 小时前
【大白话说Java面试题 第74题】【Mysql篇】第4题:InnoDB 和 MyISAM 的数据文件存储区别?
java·开发语言·mysql·面试
qq_25183645710 小时前
基于java Web快乐岛儿童网站设计与实现
java·开发语言·前端