Drools入门之规则文件
规则文件
Drools规则引擎中,标准的规则文件就是以“.drl”结尾的文本文件,由于它是标准的文本文件,因此可以通过一些记事本工具对其进行查阅和编辑。规则内容是放在规则文件中的,一个规则文件可以存放多个规则体。除此之外,规则文件还可以存放用户自定义的函数、数据对象及自定义查询等。
一套完整的规则文件内容如下图所示
package:除package之外,其他关键字在规则文件中的顺序是任意的,规则文件中必须要有一个package声明,并且package声明要放在规则文件的第一行(规则模板除外)。规则文件中的package和Java语言中的package有相似之处,不同的是在Java文件中package是用来把功能相似或相关的文件放在同一个package下进行管理。这种package管理既有物理上Java文件位置的管理,又有逻辑上文件位置的管理;在Java文件中通过package管理文件要求文件位置在逻辑上与物理上都要保持一致。在Drools规则引擎的规则文件中,package对于规则文件中规则的管理只限于逻辑上的管理,并不管规则文件所在的物理目录,这是规则文件与Java类文件中package的区别。
同一个package下,用户可以自定义函数、自定义查询等,不管这些函数与查询是否在同一个规则文件中,都是可以直接使用的,这与Java中同一package的Java类调用相似。
import:用来导入类名或静态方法。global:又称全局变量,使用时需要单独定义变量类型。function:自定义函数,读者可以理解为Java静态方法的一种变形,与JavaScript函数定义相似。queries:表示查询,具体说明请查阅相关章节进行学习。rule end:规则内容中的规则体,是进行业务规则判断、处理业务结果的部分,也是本节主讲的核心内容之一。
规则体语法结构
规则体语法结构如图所示
一个规则体包含的3个部分,唯有attributes部分是可选的,其他关键字都是必填信息。属性可选并不表示没有,属性是有默认值的,如规则默认是被激活的。
匹配模式
LHS部分由一个或多个条件组成,条件又称为pattern。多个pattern之间既可以使用and或or进行连接,又可以使用小括号确定pattern的优先级,默认条件是true。
其语法结构为:[绑定变量名:Object(Field约束)]
例子:$p:Person(age == “20”,name == “张三”)
规则体中LHS部分绑定变量基本上有两种形式:一种是整个Fact变量的绑定,另一种是约束条件属性变量的绑定。
第一种方式,绑定对象:
rule "test003"
when
$p:Person(age == "20",name == "张三")
then
System.out.println("张三的年龄为20");
end
第二种方式,绑定属性:
rule "test004"
when
Person(age == "20",$n:name == "张三")
then
System.out.println("姓名是:"+$n);
end
运算符
运算符是在程序中最常用的计算方法,一般的运算符包括“+”“-”“*”“/”“%”等,优先级与Java相同。
其中,在%取模运算上,规则需要控制优先级,即先运算后匹配。如:$p:Person((age%2)==10)
约束连接
匹配模式中可以有多种约束符的连接,常用的有“&&”(and)、“||”(or)和“,”(and)。这3个连接符号如果没有用括号来显示定义的优先级,那么“&&”优先级大于“||”优先级。从表面上看“,”与“&&”具有相同的含义。
在Drools 6.4版本中,“,”与“&&”和“||”不能混合使用,即在有“&&”或“||”出现的LHS部分,是不可以有“,”连接符出现的,反之亦然。在Drools 7.10版取消了这个限制
Drools自带的约束条件
contains| not contains
memberOf | not memberOf
matches | not matches
-
contains比较操作符
contains是用来检查一个Fact对象的某个属性值是否包含一个指定的对象值。其语法格式为:
Object( field[Collection/Array] contains|not contains value)
-
memberOf比较运算符
memberOf用来判断某个Fact对象的某个字段是否在一个或多个集合中。memberOf的语法为
Object(fieldName memberOf|not memberOf value[Collection/Array])
-
matches比较运算符
matches用来对某个Fact对象的字段与标准的Java正则表达式进行相似匹配,被比较的字符串可以是一个标准的Java正则表达式。但需要读者注意的是,正则表达式字符串中不用考虑“\”的转义问题,其语法为
Object(fieldName matches | not matches "正则表达式")
-
soundslike比较运算符
soundslike用来检查单词是否具有与给定值几乎相同的声音(使用英语发音)。基于Soundex算法的语法为:
Object(fieldName soundslike 'value')
-
str比较运算符
str不仅检查String字段是否以某一值开头/结尾,还可以判断字符串长度,其语法为:
Object(fieldName str[startsWith|endsWith|length] "String"|1)