繁体   English   中英

在 Drools 中设置和获取全局变量

[英]Setting and getting a Global variable in Drools

我在 drl 文件中有这样的内容:

import java.lang.String

global String result;

rule ''Rule 1'' when some condition
    then 
result = "PASS";
kcontext.getKnowledgeRuntime().setGlobal("Result", result); // I got an "Unexpected global" exception.
System.out.println("result = "+ Result);

另外,我不知道如何从 MyService.java class 访问这个全局变量。

您的规则不应触及“kcontext”。 你到底想做什么? result = "PASS"足以设置全局的值。

global String result

rule "Rule 1" 
when 
  // some condition
then 
  result = "PASS";
end

当然,它不会像您希望的那样工作,因为您需要更改现有 object 的值; 你不能那样覆盖它。 某些选项可能是 class 的“ResultsHolder”类型,您可以设置 boolean 变量; 或者甚至是你可以调用的AtomicBoolean

要使用全局触发规则,您需要在调用规则之前将全局对象添加到 KieBase:

var value = ...; // some OBJECT which you are going to pass in as a global

KieSession session = ruleBase.newStatefulSession();
session.insert(...); // insert data
session.setGlobal( "myGlobalFoo", value ); // sets the global; note the name must match the rule file!
session.fireAllRules();

触发规则后,您将获得对可以使用的value的引用。 这也是为什么您不能将字符串作为全局变量传递并期望它们捕获更改的原因——Java 是按值传递,而不是按引用传递。


这是将结果传递到规则之外的示例。 这个玩具应用程序将检查学生的考试成绩,然后决定他们是通过还是失败。

课程:

class Student {
  private String name;
  public String getName() { return this.name; }
  public void setName(String name) { this.name = name; }
}

class Exam {
  private String name;
  private Double score;
  public String getName() { return this.name; }
  public void setName(String name) { this.name = name; }
  public Double getScore() { return this.score; }
  public void setScore(String score) { this.score = score; }
}

class ExamResults {
  private List<String> results = new ArrayList<>();
  public void logResults( String name, Double score, boolean passed ) {
    this.results.add(name + " scored " + score + "%, which is a " + (passed ? "passing": "failing") + " grade.");
  }
  public List<String> getResults() { return this.results; }
}

规则:

global ExamResults results;

rule "Evaluate exam"
when
  Student( $name: name )
  Exam ( $score: score, name == $name )
then
  boolean passed = $score > 60.0;
  results.logResults( $name, $score, passed );
end

调用:

List<Student> students = ...;
List<Exam> exams = ... ;
ExamResults results = new ExamResults();

KieSession session = ruleBase.newStatefulSession();
students.forEach( student -> session.insert(students) );
exams.forEach( exam -> session.insert(exam) );
session.setGlobal( "results", results);
session.fireAllRules();

// Print the results:
results.getResults().forEach(System.out::println);

如果您要做的只是从您的规则中获取一些数据(例如,某些条件是否匹配),我已经在此处此处编写了有关如何执行此操作的答案。 如果您只想知道触发了哪些规则,您应该编写一个记录规则命中的侦听器(“afterMatchFired”)。

我试图从drl文件中设置一个全局变量,而不是我的java class,如服务class。

我所要做的就是以下,它成功地工作了

导入 java.lang.String

全局字符串结果;

规则“规则 1”时
一些条件

然后

String grade = "PASS";

kcontext.getKnowledgeRuntime().setGlobal("result", grade);  
                                                                                                                

结尾

此外,全局变量名称应与我在 setGlobal("result",...) 上传递的名称相匹配。

然后使用我在服务 class 中的 session 获取全局变量。 喜欢:

session.getGlobal("结果");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM