一、equality modes介绍

drools中存在如下2种equality modes。

1、identity模式

identity:这是默认的情况。drools引擎使用IdentityHashMap保存所有插入到工作内存中的Fact对象。对于每次插入一个新的对象,则会返回一个新的FactHandle对象。如果是重复插入对象,则返回已经存在的FactHandle对象。

举例:

Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);

针对以上例子, factHandle1 != factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在2个Person对象。

2、equality模式

equality:drools引擎使用HashMap保存所有插入到工作内存中的Fact对象。在这种模式下,如果向drools中插入一个新的对象,只有这个对象不存在(根据对象的hashcodeequals判断)才会返回一个新的FactHandle否则返回已经存在的FactHandle

举例:

// 重写了Person对象的hashcode和equals方法
Person p1 = new Person("zhangsan", 20, "湖北罗田");
Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
FactHandle factHandle1 = kieSession.insert(p1);
FactHandle factHandle2 = kieSession.insert(p2);
FactHandle factHandle3 = kieSession.insert(p2);

针对以上例子, factHandle1 == factHandle2但是 factHandle2 == factHandle3。即工作内存中会存在1个Person对象。

二、需求

我们存在一个Person对象,存在如下3个属性name,age和address,其中重写对象的name和age的hashcode和equals方法。

  • 多次向工作内存中插入对象,看产生的结果。
  • 插入同一个对象看获取到的FactHandle对象是否是同一个。

三、如何设置fact对象的equality行为

此处介绍一个通过kmodule.xml配置的方法

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="kbase-identity" packages="rules" default="false" equalsBehavior="identity">
        <ksession name="ksession-01" default="false" type="stateful"/>
    </kbase>
    <kbase name="kbase-equality" packages="rules" default="false" equalsBehavior="equality">
        <ksession name="ksession-02" default="false" type="stateful"/>
    </kbase>
</kmodule>

通过上方的代码可知是通过配置kbase下的equalsBehavior属性来配置。

其余的配置方法,参考下图:

四、编码实现

1、项目结构图

2、倒入jar包

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-bom</artifactId>
            <type>pom</type>
            <version>7.69.0.Final</version>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-mvel</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.11</version>
    </dependency>
</dependencies>

3、编写Person对象

public class Person {
    private String name;
    private Integer age;
    private String address;
    public Person(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) && Objects.equals(age, person.age);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

注意:
此对象需要重写hashcode和equals方法。

4、编写kmodule.xml文件

在此配置文件中,需要在kbase上指定equalsBehavior,用来确定Fact对象的equality modes。

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="kbase-identity" packages="rules" default="false" equalsBehavior="identity">
        <ksession name="ksession-01" default="false" type="stateful"/>
    </kbase>
    <kbase name="kbase-equality" packages="rules" default="false" equalsBehavior="equality">
        <ksession name="ksession-02" default="false" type="stateful"/>
    </kbase>
</kmodule>

注意:
需要看2个equalsBehavior的取值

5、编写一个规则文件

package rules
import com.huan.drools.Person
// 定义规则
rule "rule_01"
    when
        $p: Person()
    then
        System.out.println(Thread.currentThread().getName()   " name:" $p.getName() " age:" $p.getAge());
end

规则文件中的内容很简单,只要工作内存中存在Person对象,那么就输出这个对象的nameage的值。

6、identity模式测试

1、编写测试代码

public class DroolsApplication {
    public static void main(String[] args) {
        equalsBehaviorIdentity();
    }
    private static void equalsBehaviorIdentity() {
        KieServices kieServices = KieServices.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        // 注意此处的 ksession-01
        KieSession kieSession = kieContainer.newKieSession("ksession-01");
        kieSession.addEventListener(new DebugRuleRuntimeEventListener());
        Person p1 = new Person("zhangsan", 20, "湖北罗田");
        Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
        FactHandle factHandle1 = kieSession.insert(p1);
        FactHandle factHandle2 = kieSession.insert(p2);
        FactHandle factHandle3 = kieSession.insert(p2);
        kieSession.fireAllRules();
        kieSession.dispose();
    }   
}

2、运行结果

具体的解释见上图中的说明。

7、equality模式测试

1、编写测试代码

public class DroolsApplication {
    public static void main(String[] args) {
        equalsBehaviorEquality();
    }
    private static void equalsBehaviorEquality() {
        KieServices kieServices = KieServices.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession("ksession-02");
        kieSession.addEventListener(new DebugRuleRuntimeEventListener());
        Person p1 = new Person("zhangsan", 20, "湖北罗田");
        Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
        FactHandle factHandle1 = kieSession.insert(p1);
        FactHandle factHandle2 = kieSession.insert(p2);
        FactHandle factHandle3 = kieSession.insert(p2);
        kieSession.fireAllRules();
        kieSession.dispose();
    }
}

2、运行结果

五、结论

针对如下代码,看看在不同equality modes下的行为

 Person p1 = new Person("zhangsan", 20, "湖北罗田");
 Person p2 = new Person("zhangsan", 20, "湖北黄冈罗田");
 FactHandle factHandle1 = kieSession.insert(p1);
 FactHandle factHandle2 = kieSession.insert(p2);
 FactHandle factHandle3 = kieSession.insert(p2);

Person对象的hashcode和equals方法进行重写了,根据构造方法的前2个参数。

1、identity模式下

factHandle1 != factHandle2 因为p1和p2是2个不同的对象。
factHandle2 == factHandle3 因为是p2重复加入工作内存,这个时候工作内存中已经存在了,所以返回之前关联的FactHandle

2、equality模式下

factHandle1 == factHandle2 == factHandle3 因为这种模式下,是需要根据对象的equalshashcode方法进行比较,而Person对象重写了这2个方法,所以返回的是同一个。

六、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-fact-equality-modes

七、参考链接

1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#fact-equality-modes-con_decision-engine

到此这篇关于drools中Fact的equality modes的文章就介绍到这了,更多相关drools equality modes内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

深入浅析drools中Fact的equality modes的更多相关文章

  1. drools中then部分的写法(推荐)

    本文介绍一下drools中then部分的写法,以及一些内置的方法,比如insert/delete/modify等等。同时也介绍一下rule的继承,和在when中实现if else if 等操作,感兴趣的朋友跟随小编一起看看吧

  2. SpringBoot集成drools的实现示例

    本文主要介绍了SpringBoot集成drools的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. drools的简单入门案例场景分析

    drools是一款由JBoss组织提供的基于Java语言开发的开源规则引擎,可以将复杂且多变的业务规则从硬编码中解放出来,这篇文章主要介绍了drools的简单入门案例,需要的朋友可以参考下

  4. 深入浅析drools中Fact的equality modes

    这篇文章主要介绍了drools中Fact的equality modes的相关知识,本文通过图文实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. drools中使用function的方法小结

    当我们在drools中编写规则时,有些时候存在重复的代码,那么我们是否可以将这些重复代码抽取出来,封装成一个function来调用呢?那么在drools中如何自定义function?下面小编给大家介绍下drools中使用function的方法,需要的朋友可以参考下

  6. 聊聊drools session的不同

    在drools中存在2种session,一种是有状态的Session (Stateful Session),另外一种一种是无状态的Session (Stateless Session,本文通过实例代码给大家介绍drools session的不同,感兴趣的朋友一起看看吧

  7. drools中query的用法小结

    这篇文章主要介绍了drools中query的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. drools规则语法一

    在drools中有一些核心特性就是通过mvel来实现的。有时候,规则和规则之间存在冲突,drools使用冲突解决策略来解决矛盾。

  9. drools – 在TaskClient上调用activate方法时获取java.lang.NullPointerException

    在客户端对象上调用activate方法时获取空指针异常.这是我的代码.我得到以下例外我在调试时看到了客户端对象,但它不是null.不知道为什么我收到此错误.我在“client.activate()”行而不是“client.connect()”收到此错误.解决方法根据堆栈跟踪,出现此错误,因为MinaTaskClientConnector中的会话为空.据我所知,源代码为TaskClient和Mina

  10. java – 直接从存储库加载Drools/KIE Workbench工件

    /-1.0.0.jar)是.是的,我可以直接从浏览器访问存储库中的.jar,无需身份验证.任何想法或教程如何做到这一点?

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部