我第一次接触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,因为我读过这不是一个好习惯),因此考虑是否存在条件匹配我通过的对象中有一对?
您建议采取其他解决方法吗?
提前感谢
答案 0 :(得分:1)
不,不会。
for(Log l : logs) {
kieS.insert(l);
kieS.fireAllRules();
}
根据您的循环,您将插入一个对象,并且在每次插入后立即触发所有规则。我不确定Drools将如何响应您的循环,但是您可能想做的是将所有Logs插入工作内存中,然后触发规则:
for(Log l : logs) {
kieS.insert(l);
}
kieS.fireAllRules();
设计JUnit测试类会立即向您显示。