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號