《Drools7.0.0.Final规则引擎教程》番外实例篇——activation-group的多FACT对象

简介: 《Drools7.0.0.Final规则引擎教程》番外实例篇——activation-group的多FACT对象

场景

当我们使用activation-group时,默认会执行优先级最高的一个规则,然后其他规则不再执行,这也是此属性的基本特性。那么,大家是否考虑过这样一个问题,那就是如果在调用fireAllRules方法之前,insert了多个对象,那么应该触发几次规则?


在其他属性的使用时,我们知道,如果插入多个对象,那么如果每个对象都符合同一规则条件就会执行多次,如果部分条件符合规则,就执行部分次。当我们即想使用activation-group的特性,又想实现上面的要求时改如何去做呢?


实例解析

实例一

首先,我们来确认第一个问题,insert多个FACT对象,会触发几次规则。


@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();
        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();
        Product p2 = new Product();
        p2.setDiscount(20);
        Product p1 = new Product();
        p1.setDiscount(10);
        kSession.insert(p2);
        kSession.insert(p1);
        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }
package com.rules
import com.secbro.drools.model.Product
 rule "test-activation-group1"
    activation-group "foo"
    when
        $obj : Product()
    then
        System.out.println("test-activation-group1 被触发");
    end
rule "test-activation-group2"
    activation-group "foo"
    salience 1
    when
    $obj : Product()
    then
        System.out.println("test-activation-group2 被触发 discount= " + $obj.getDiscount());
    end

执行的结果如下:


test-activation-group2 被触发 discount= 10

第一次执行命中了1条规则!

很显然,插入了两个FACT对象,只触发了一次规则。


实例二

那么,我们想达到上面说的,如果插入多个对象,每个符合条件的都触发一次,同时一个activation-group组中只触发优先级比较高的。

这就需要我们修改改代码如下:

@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();
        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();
        Product p2 = new Product();
        p2.setDiscount(20);
        kSession.insert(p2);
        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        Product p1 = new Product();
        p1.setDiscount(10);
        kSession.insert(p1);
        count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }

执行结果:


test-activation-group2 被触发 discount= 20

第一次执行命中了1条规则!

test-activation-group2 被触发 discount= 10

第一次执行命中了1条规则!

像上面这样,每执行一次调用一次fireAllRules就达到了预期的目的。


另外一种方式就是不使用activation-group方法,而采用delete方法。

@Test
    public void testRules() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();
        KieSession kSession = kieContainer.newKieSession("ksession-rule");
        kSession.getAgenda().getAgendaGroup("foo").setFocus();
        Product p2 = new Product();
        p2.setDiscount(20);
        kSession.insert(p2);
        Product p1 = new Product();
        p1.setDiscount(10);
        kSession.insert(p1);
        int count = kSession.fireAllRules();
        System.out.println("第一次执行命中了" + count + "条规则!");
        kSession.dispose();
    }
package com.rules
import com.secbro.drools.model.Product
 rule "test-activation-group1"
//    activation-group "foo"
    when
        $obj : Product()
    then
        delete($obj)
        System.out.println("test-activation-group1 被触发");
    end
rule "test-activation-group2"
//    activation-group "foo"
    salience 1
    when
    $obj : Product()
    then
        delete($obj)
        System.out.println("test-activation-group2 被触发 discount= " + $obj.getDiscount());
    end


目录
相关文章
|
存储 Oracle 关系型数据库
postgresql数据库|wal日志的开启以及如何管理
postgresql数据库|wal日志的开启以及如何管理
2096 0
remote: HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2
remote: HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2
5126 0
|
人工智能 自然语言处理 算法
开放式API在AI应用开发中的革命性角色
【7月更文第21天】随着人工智能技术的飞速发展,开放式API(Application Programming Interfaces)正逐渐成为连接技术与创新、加速AI应用开发的关键桥梁。这些API允许开发者轻松访问预先训练好的模型和复杂算法,无需从零开始构建基础架构,从而极大地降低了AI应用的开发门槛,促进了技术民主化。本文将探讨开放式API如何在AI领域引发革命性变化,通过实际案例和代码示例展现其强大功能。
524 2
|
XML JavaScript 前端开发
如何在JavaScript中设置多个样式属性?
【6月更文挑战第29天】如何在JavaScript中设置多个样式属性?
777 3
|
监控 NoSQL MongoDB
mongodb查询100万数据如何查询快速
综上,提高MongoDB百万级数据的查询性能需要综合多项技术,并在实际应用中不断调优和实践。理解数据的特征,合理设计索引,优化查询语句,在数据访问、管理上遵循最佳的实践,这样才能有效地管理和查询大规模的数据集合。
679 1
|
存储 负载均衡 NoSQL
一文让你搞懂 zookeeper
一文让你搞懂 zookeeper
16779 15
|
存储 NoSQL 算法
MongoDB保姆级指南(中):从副本集群、分片集群起航,探索分布式存储的趋势!
本文一起来聊聊MongoDB集群,顺带以MongoDB集群为起点,共同探讨一下分布式存储的发展趋势~
2671 15
|
存储 负载均衡 监控
redis 集群模式(redis cluster)介绍
redis 集群模式(redis cluster)介绍
|
存储 NoSQL 关系型数据库
MongoDB 的集群架构与设计
MongoDB 的集群架构与设计
4097 0