如何在多个对象上正确触发Drools规则?

时间:2019-05-22 12:19:11

标签: java java-ee drools

我第一次接触Drools(使用Java),我对它的会话和使用对象集合的能力感到困惑。 就是这种情况:

我正在构建一个由休息服务组成的Web应用程序。

我有一个名为Log的类,其中有两个字段(eventType和RiskLevelId)。

Mycode在定义的时间范围内从数据库中检索了几种此类对象。

如果该对象集合恰好包含一个eventType == 2和RiskLevelId == 1的日志以及另一个EventType == 3和RiskLevelId == 1的日志,则应该执行规则。

通过Drools接口,我可以正确检索KieServices,KieBuilder,KieContaier,KieBase和KieSession。

try {
        // load up the knowledge base
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        FileInputStream fis = f;
        kfs.write( "src/main/resources/simple.drl",
                kieServices.getResources().newInputStreamResource( fis ) );
        KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
        Results results = kieBuilder.getResults();
        if( results.hasMessages( Message.Level.ERROR ) ){
            System.out.println( results.getMessages() );
            throw new IllegalStateException( "### errors ###" );
        }
        KieContainer kieContainer = kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );
        KieBase kieBase = kieContainer.getKieBase();
        kieSession = kieContainer.newKieSession();




    }catch (Throwable t) {
        t.printStackTrace();
    }
然后,

i在for循环中检索每个单个Log距离。停留在循环中,我还将对象添加到KieSession并触发规则:

@Autowired
KieSessionFactory kieSessionFactory;



@Override
public void run() {

    KieSession kieS =  kieSessionFactory.getKieSessionCheckSavedLog();

    try {
        List<Log> logs = logRepo.getAllInGivenTimeSec(10);
        for(Log l : logs) {
            kieS.insert(l);
            kieS.fireAllRules();
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

这是我写的规则:

package com.sample 
import it.protodrools.beans.Log;

dialect "java"

rule "log2"
    when
        $l1 : Log( eventType == 2 && riskLevelId == 1);
        $l2 : Log( this != $l1 && eventType == 3 && riskLevelId == 1 );
    then
       System.out.println( "deadly threat !" );
end

我的问题是:该规则将考虑我正在传递的对象的整个列表(虽然不是通过List,因为我读过这不是一个好习惯),因此考虑是否存在条件匹配我通过的对象中有一对?

您建议采取其他解决方法吗?

提前感谢

1 个答案:

答案 0 :(得分:1)

不,不会。

for(Log l : logs) {
    kieS.insert(l);
    kieS.fireAllRules();
}

根据您的循环,您将插入一个对象,并且在每次插入后立即触发所有规则。我不确定Drools将如何响应您的循环,但是您可能想做的是将所有Logs插入工作内存中,然后触发规则:

for(Log l : logs) {
    kieS.insert(l);
}
kieS.fireAllRules();

设计JUnit测试类会立即向您显示。