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号
浙公网安备 33010602011771号