Drools规则:
从代码中分离 内采用RETE高效规则匹配算法
最近做的一个项目中还是分离出总结一下 主要就是涉及计算问题
如果我们要在符合的条件下加加减减 就需要在逻辑中ifelse很多 而且出现错误会影响整个项目的问题

然后我们用一个案例直接上手测验
大概总的

三步走
一.依赖
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
<version>${drools.version}</version>
</dependency>
<!--kie是其drools父亲 drools 作为规则引擎,是 KIE 平台的核心组件之一-->
<!-- <dependency>-->
<!-- <groupId>org.kie</groupId>-->
<!-- <artifactId>kie-api</artifactId>-->
<!-- <version>${drools.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.kie</groupId>-->
<!-- <artifactId>kie-internal</artifactId>-->
<!-- <version>${drools.version}</version>-->
<!-- </dependency>-->
注意注意!!! 千万别注入注释掉的依赖 后面出现一大堆问题 明明实现逻辑没有任何问题
把其父类kie注入 导致使用出现问题 我们只是使用其一个组件drools而已
二.drools.drl配置规则文件
规则文件.drl构成:
package 包名,只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用
import 用于导入类或者静态方法
global 全局变量
function 自定义函数
query 查询
rule end 规则体
例如:
package rules
import com.gao.zhengjiao.entity.Account
import com.gao.zhengjiao.entity.Reward
规则体:
rule "one"
no-loop true
when
$account: Account(points >= 200, isVIp == 0)
then
System.out.println("规则触发: " + $account.getAccountName() + " 积分达到 " + $account.getPoints() + ",升级为VIP");
modify($account) {
setIsVIp(1)
};
end
规则体就是:
rule 随便名字
属性
when 条件
then 符合条件后需要做的
(常用后面主要测验 insert update retract)
end 结束
我们要测验的drl文件放在resources下的rules文件夹下 位置很重要 为后续的配置文件映射使用
完整.drl文件:
package rules
import com.gao.zhengjiao.entity.Account
import com.gao.zhengjiao.entity.Reward
// 规则1: 积分超过200分成为VIP (使用update)
rule "one"
no-loop true
when
$account: Account(points >= 200, isVIp == 0)
then
System.out.println("规则触发: " + $account.getAccountName() + " 积分达到 " + $account.getPoints() + ",升级为VIP");
// $account.setIsVIp(1);
// update($account);
modify($account) {
setIsVIp(1)
};
end
// 规则2: VIP用户积分超过500分给予现金奖励 (使用insert)
rule "two"
when
$account: Account(isVIp == 1, points >= 500)
then
System.out.println("规则触发: " + $account.getAccountName() + " 作为VIP积分超过500,给予现金奖励");
Reward reward = new Reward($account.getAccountName(), 100.0);
insert(reward);
modify($account){
setBalance($account.getBalance() + 100)
}
end
// 规则3: 处理低积分VIP用户 (使用retract完全移除)
//retract($account): 这会将整个 Account 对象从工作内存中移除
//后续规则影响: 一旦 retract 执行,该 Account 对象将不再参与后续任何规则的匹配
//这种方式适用于你需要完全移除用户数据的场景
rule "three"
when
$account: Account(isVIp == 1, points < 100)
then
System.out.println("规则触发: " + $account.getAccountName() + " 积分过低,移除用户信息");
retract($account);
end
三.drools配置config
这个就是调用drools使用它 类似于一个工厂注入bean中使用 而不再编写xml文件 是固定的格式
@Configuration
public class DroolsAutoConfiguration {
private static final KieServices kieServices = KieServices.Factory.get();
private static final String RULES_CUSTOMER_RULES_DRL = "rules/points-rules.drl";
@Bean
public KieContainer kieContainer() {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
return kieContainer;
}
}
开始测验验证:
@Autowired
private KieContainer kieContainer;
@Test
void contextLoads() {
//从Kie容器对象中获取会话对象
KieSession kieSession = kieContainer.newKieSession();
Account account =new Account(0, "高远", 255, 1000.0);
Account account2 =new Account(1, "郑娇", 888, 2000.0);
Account account3 =new Account(1, "zhang", 55, 100.0);
List<Account> accounts = new ArrayList<>();
accounts.add(account);
accounts.add(account2);
accounts.add(account3);
System.out.println("=== 规则执行前 ===");
for (Account a : accounts) {
System.out.println(a);
}
kieSession.insert(account);
kieSession.insert(account2);
kieSession.fireAllRules();
System.out.println("\n=== 规则执行后 ===");
for (Account a : accounts) {
System.out.println(a);
}
kieSession.dispose();
}
运行结果逻辑大概如下
逻辑实现很容易 就是困扰的我一直以为哪里编写错了 搞了半天原来是maven依赖的问题。。。。。。





浙公网安备 33010602011771号