drools-基础语法

drools-基础语法

起男 169 2023-05-14

drools-基础语法

drl是drools rule language的缩写。在规则文件中编写具体的规则内容,一套完整的规则文件的内容构成如下:

  • package:包名,package对应的不一定是真正的目录,可以任意写com.xxx,同一个包下的drl文件可以相互访问
  • import:用于导入类或者静态方法
  • global:全局变量
  • function:自定义函数
  • query:查询
  • rule end:规则体

规则体语法结构

一个规则体通常包括三个部分:属性部分(attribute)、条件部分(LHS)和结果部分(RHS)

	rule "ruleName" //rule关键字,表示规则开始,参数为规则的唯一名称
		attributes  //规则属性,是rule与when之间的参数,为可选项
	when		//关键字,后面是规则的条件部分
		LHS		//是规则的条件部分
	then		//关键字,后面跟规则的结果部分
		RHS		//规则的结果或行为
	end				//关键字,表示一个规则的结束

条件部分

LHS(left hand side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素(自动添加一个eval(true)

LHS部分由一个或者多个条件组成,条件又称为pattern,其语法结构为:绑定变量名:Object(Field约束)

  • 绑定变量名可以省略,通常绑定变量名的命名一般建议以$开始。如果定义了绑定变量名,就可以在规则体的RHS部分使用此绑定变量名来操作相应的fact对象。
  • Field约束部分是需要返回true或者false的0个或多个表达式
  • 工作内存中必须存在Object这种类型的Fact对象(类型约束),并且其Field约束中使用到的属性也必须存在(属性约束)

约束连接

在LHS中,可以包含0~n个条件,多个pattern之间可以采用&&,或者不写来代表and,也可以使用||来代表or。例如:

$Order:(amout>=100 && amout<=500)

比较操作符

在drools中提供了12种类型的比较操作符

操作符 说明
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于
contains 检查一个fact对象的某个属性值是否包含一个指定的对象
not contains 检查一个fact对象的某个属性值是否不包含一个指定的对象
memberOf 判断一个fact对象的某个属性是否在一个或多个集合中
not memberOf 判断一个fact对象的某个属性是否不在一个或多个集合中
matches 判断一个fact对象的属性是否与提供的标准的java正则表达式匹配
not matches 判断一个fact对象的属性是否不与提供的标准的java正则表达式匹配

结果部分

insert

insert函数的作用和我们在java类中调用StatefullKnowledgeSession对象的insert方法的作用相同,都是用来将一个fact对象插入到当前的working memory当中

注意:

一旦调用insert函数,那么drools会重新与所有的规则再重新匹配一遍,对于没有设置no-loop属性为true的规则,如果条件满足,不管之前是否执行过都会再执行一次,这个特性不仅存在于insert函数上,update、retract也具有该特性,所以在某些情况下因考虑不周调用insert、update或retract容易发生死循环

update

update函数用来实现对当前working memory当中的fact进行更新,用来告诉当前的working memory该fact对象已经发生了变化

retract

retract函数用来将working memory当中的某个fact对象从working memory中删除

属性部分

属性名 说明
salience 指定规则执行优先级,数字越大优先级越高,默认为0
dialect 指定规则使用的语言类型,取值为java和mvel
enabled 指定规则是否启用
date-effective 指定规则生效时间
date-expires 指定规则失效时间
activation-group 激活分组,具有相同分组名称的规则只能有一个触发,可以通过优先级来选择谁执行
agenda-group 议程分组,只有获取焦点的组才有可能触发。通过kieSession.getAgenda().getAgendaGroup("xxx")或者auto-focus来设置焦点
timer 定时器,指定规则触发时间。例如timer(5s 2s)5秒后触发,每两秒执行一次;timer(cron:0/1 * * * * ?)每隔1秒触发一次
auto-focus 自动获取焦点,一般结合agenda-group一起使用
no-loop 用来控制已经执行过的规则在条件满足的时候是否再次执行,防止死循环

drools中的时间格式默认是“dd-MMM-yyyy”,如果要修改的话,可以通过System.setProperty(“drools.dateformat”,“yyyy-MM-dd”)来设置

全局变量

全局变量,一般用作执行规则后的结果数据返回或对具体某个服务调用等。定义完全局变量之后,所有的规则中都可以获取和操作定义的全局变量对象

语法:global 对象类型 对象名

可以在java代码中通过kieSession.setGlobal("对象名",对象)的方式获取配置文件中的全局变量

query查询

query语法提供了一种查询working memory中符合约束条件的fact对象的简单方法。它仅包含规则文件中LHS部分,不同指定“when”和“then”部分。query有一个可选参数集合,每一个参数都有可选类型。如果没有指定类型,则认为Object类型。引擎会尝试强转为需要的类型

对于KieBase来说,query的名字是全局性的,因此不要向同一RuleBase的不同包添加相同名称的query

使用kieSession.getQueryResults(“query_name”)的方法获得查询的结果,方法返回一个列表,从中可以获取匹配查询到的对象

例如:

	//无参数
	query "q1"
	    $order:Order(amout>100)
	end
	//带参数
	query "q2" (String amoutParam)
	    $order:Order(amout==amoutParam)
	end
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.newKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();

        Order o1 = new Order();
        o1.setAmout(300);
        Order o2 = new Order();
        o2.setAmout(50);
        kieSession.insert(o1);
        kieSession.insert(o2);

        QueryResults qr = kieSession.getQueryResults("q1");
        for (QueryResultsRow row : qr) {
            System.out.println(row.get("$order"));
        }
        System.out.println("----------------");
        QueryResults qr2 = kieSession.getQueryResults("q2", 50);
        for (QueryResultsRow row : qr2) {
            System.out.println(row.get("$order"));
        }
        kieSession.dispose();

function函数

在规则中可以通过函数来做一些通用的逻辑,相当于java类中的方法一样

例如:

	function String format(String name){
	    return "hello" + name;
	}

函数的参数类型和返回值类型和java一样