Drools 规则学习

Drools 规则学习java

在 Drools 当中,一个标准的规则文件就是一个以“.drl”结尾的文本文件,因为它是一
个标准的文本文件,因此能够经过一些记事本工具对其进行打开、查看和编辑。规则是放在
规则文件当中的,一个规则文件能够存放多个规则,除此以外,在规则文件当中还能够存放
用户自定义的函数、数据对象及自定义查询等相关在规则当中可能会用到的一些对象。
文件结构图以下:
package
imports
globals
functions
queries
rules
.....正则表达式

对于一个规则文件而言,首先声明 package 是必须的,除 package 以外,其它对象在规
则文件中的顺序是任意的,也就是说在规则文件当中必需要有一个 package 声明,同时
package 声明必需要放在规则文件的第一行。一个规则一般包括三个部分:属性部分(attribute) 、条件
部分(LHS)和结果部分(RHS) 一个标准规则的结构以下:
rule "name"
attributes
when
LHS
then
RHS
end函数

1.在 LHS 当中,能够包含 0~n 个条件,若是 LHS 部分没空的话,那么引擎会自动添加一个 eval(true)的条件,因为该条件老是返回 true,因此 LHS 为空的规则老是返回 true
2.在这两个pattern没有符号链接, 在Drools当中在 pattern 中没有链接符号,那么就用 and 来做为默认链接,因此在该规则的 LHS 部分中两个 pattern 只有都知足了才会返回 true。默认状况下,每行能够用“;”来做为结束符(和Java 的结束同样) ,固然行尾也能够不加“;”结尾。工具


条件部分
1.约束链接
对于对象内部的多个约束的链接,能够采用“&&” (and) 、 “||”(or)和“,”(and)来实现
示例代码:
rule "rule1"
when
Customer(age>20 || gender==’male’&& city==’sh’)
then
<action>…
End

2.比较操做符
在 Drools当中共提供了十二种类型的比较操做符, 分别是: >、 >=、 <、 <=、 = =、 !=、 contains、 not contains、memberof、not memberof、matches、not matches;在这十二种类型的比较操做符当中,前六个是比较常见也是用的比较多的比较操做符
contains 示例代码:
rule "rule1"
when
$order:Order();
$customer:Customer(age >20, orders contains $order);
then
System.out.println($customer.getName());
endoop

not contains 示例代码:
rule "rule1"
when
$order:Order(items not contains "手机");
then
System.out.println($order.getName());
end

memberOf(memberOf 是用来判断某个 Fact 对象的某个字段是否在一个集合(Collection/Array)当中) 示例代码:
global String[] orderNames; //定义全局变量
rule "rule1"
when
$order:Order(name memberOf orderNames);
then
System.out.println($order.getName());
end

not memberOf (该操做符与 memberOf 做用洽洽相反) 示例代码:
rule "rule1"
when
$orderList:String[]();
$order:Order(name not memberOf $orderList);
then
System.out.println($order.getName());
end

matches 是用来对某个 Fact 的字段与标准的 Java 正则表达式进行类似匹配,被比较的字符串能够是一个标准的 Java 正则表达式,但有一点须要注意,那就是正则表达式字符串当中不用考虑“\”的转义问题。
示例代码:
rule "rule1"
when
$customer:Customer(name matches "李.*");
then
System.out.println($customer.getName());
end学习

not matches (该操做符与 matches 做用洽洽相反)操作系统

结果部分线程

咱们知道,在规则当中 LHS 就是用来放置条件的,因此在 RHS 当中虽然能够直接编写
Java 代码,但不建议在代码当中有条件判断,若是须要条件判断,那么请从新考虑将其放在
LHS 当中,不然就违背了使用规则的初衷orm

在 Drools 当中,在 RHS 里面,提供了一些对当前 Working Memory 实现快速操做的宏
宏函数或对象, 好比 insert/insertLogical、 update 和 retract 就能够实现对当前 Working Memory
中的 Fact 对象进行新增、删除或者是修改对象

1.insert
函数insert的做用与咱们在Java类当中调用StatefulKnowledgeSession对象的insert方法的做用相同,都是用来将一个 Fact 对象插入到当前的 Working Memory 当中
需注意:一旦调用 insert 宏函数,那么 Drools 会从新与全部的规则再从新匹配一次, 对于没有设置no-loop 属性为 true 的规则,若是条件知足,无论其以前是否执行过都会再执行一次,这个特性不只存在于 insert 宏函数上,后面介绍的 update、retract 宏函数一样具备该特性,因此在某些状况下因考虑不周调用 insert、update 或 retract 容易发生死循环
示例代码以下:
rule "rule1"
salience 1 //该属性的做用是经过一个数字来确认规则执行的优先级, 数字越大, 执行越靠前
when
eval(true); //默认成立
then
Customer cus=new Customer();
cus.setName("张三");
insert(cus);
end
rule "rule2"
salience 2
when
$customer:Customer(name =="张三");
then
System.out.println("rule2----"+$customer.getName());
end

2.insertLogical
insertLogical 做用与 insert 相似,它的做用也是将一个 Fact 对象插入到当前的 Working Memroy 当中

3.update
update函数意义与其名称同样, 用来实现对当前Working Memory当中的 Fact进行更新,update 宏函数的做用与 StatefulSession 对象的 update 方法的做用基本相同,都是用来告诉当
前的 Working Memory 该 Fact 对象已经发生了变化。它的用法有两种形式,一种是直接更新一个 Fact 对象,另外一种为经过指定 FactHandle 来更新与指定 FactHandle 对应的 Fact 对象
第一种 直接更新一个 Fact 对象:
rule "rule1"
salience 2
when
eval(true);
then
Customer cus=new Customer();
cus.setName("张三");
cus.setAge(1);
insert(cus);
end
rule "rule2"
salience 1
when
$customer:Customer(name=="张三",age<10);
then
$customer.setAge($customer.getAge()+1);
update($customer);
System.out.println("----------"+$customer.getName());
end

第二种 能够支持建立一个新的 Fact 对象, 从而把 FactHandle对象指定的 Fact 对象替换掉,从而实现对象的全新更新:
rule "rule1"
salience 2
when
eval(true);
then
Customer cus=new Customer();
cus.setName("张三");
cus.setAge(1);
insert(cus);
end
rule "rule2"
salience 1
when
$customer:Customer(name=="张三",age<10);
then
Customer customer=new Customer();
customer.setName("张三");
customer.setAge($customer.getAge()+1);
update(drools.getWorkingMemory().getFactHandleByIdentity($customer),customer);
System.out.println("----------"+$customer.getName());
end

4.retract
retract用来将 Working Memory 当中某个 Fact 对象从 Working Memory 当中删除 示例代码:
rule "rule1"
salience 2
when
eval(true);
then
Customer cus=new Customer();
cus.setName("张三");
cus.setAge(1);
insert(cus);
end
rule "rule2"
salience 1
when
$customer:Customer(name=="张三");
then
retract($customer);
end
5.modify
modify是一个表达式块,它能够快速实现对 Fact 对象多个属性进行修改,修改完成后会自动更新到当前的 Working Memory 当中
rule "rule1"
salience 2
when
$customer:Customer(name=="张三",age==20);
then
System.out.println("modify before customer
id:"+$customer.getId()+";age:"+$customer.getAge());
modify($customer){
setId("super man"),
setAge(30),
setName("黄五")
}
end
rule "rule2"
salience 1
when
$customer:Customer(name=="黄五");
then
System.out.println("modify after customer
id:"+$customer.getId()+";age:"+$customer.getAge());
end


属性部分
1.salience
做用是用来设置规则执行的优先级,salience 属性的值是一个数字,数字越大执行优先级越高,同时它的值能够是一个负数。默认状况下,规则的 salience 默认值为 0,因此若是咱们不手动设置规则的 salience 属性,那么它的执行顺序是随机的。
示例代码:
rule "rule1"
salience 1
when
eval(true)
then
System.out.println("rule1");
end
rule "rule2"
salience 2
when
eval(true)
then
System.out.println("rule2");
end

虽然 rule1 位于前面,但由于它的 salience 为 1,而 rule2的 salience 属性为 2,因此 rule2 会先执行,而后 rule1 才会执行。

2.no-loop
做用是用来控制已经执行过的规则在条件再次知足时是否再次执行。no-loop 属性的值是一个布尔型,默认状况下规则的 no-loop属性的值为 false,若是 no-loop 属性值为 true,那么就表示该规则只会被引擎检查一次,
若是知足条件就执行规则的 RHS 部分,若是引擎内部由于对 Fact 更新引发引擎再次启动检查规则,那么它会忽略掉全部的 no-loop 属性设置为 true 的规则。
示例代码:
rule "rule1"
salience 1
no-loop true
when
$customer:Customer(name=="张三")
then
update($customer);
System.out.println("customer name:"+$customer.getName());
End

3.date-effective 做用是用来控制规则只有在到达后才会触发,在规则运行时,引擎会自动拿当前操做系统的时候与 date-effective 设置的时间值进行比对, 只有当系统时间>=date-effective 设置的时间值时, 规则才会触发执行,不然执行将不执行。在没有设置该属性的状况下,规则随时能够触发,没有这种限制。date-effective 的值为一个日期型的字符串,默认状况下,date-effective 可接受的日期格式为“dd-MMM-yyyy” 示例代码: rule "rule1" date-effective "2009-09-25" //当前日期不小于2009-09-25时能够执行 when eval(true); then System.out.println("rule1 is execution!"); end 在实际使用的过程中,若是您不想用这种时间的格式,那么能够在调用的 Java 代码中经过使用 System.setProperty(String key,String value)方法来修改默认的时间格式 在java文件中添加此条命令: System.setProperty("drools.dateformat","yyyy-MM-dd"); 4.date-expires 做用是与 date-effective 属性偏偏相反, date-expires 的做用是用来设置规则的有效期,引擎在执行规则的时候,会检查规则有没有 date-expires 属性,若是有的话,那么会将这个属性的值与当前系统时间进行比对,若是大于系统时间,那么规则就执行,不然就不执行。 示例代码: rule "rule1" date-effective "2009-09-25" //当前日期不小于2009-09-25时能够执行(含2009-09-25) 注意修改时间格式 date-expires "2009-09-30" //当前日期大于2009-09-30时能够执行(不含2009-09-30) 注意修改时间格式 when eval(true); then System.out.println("rule1 is execution!"); end 5.enabled 做用是用来定义一个规则是否可用的。该属性的值是一个布尔值,默认该属性的值为 true,表示规则是可用的。设置其 enabled 属性值为 false,那么引擎就不会执行该规则 6.dialect 做用是用来定义规则当中要使用的语言类型,目前支持两种类型的语言:mvel 和 java,默认状况下,若是没有手工设置规则的 dialect,那么使用的 java 语言 7.duration 做用是将在该属性指定的值以后在另一个线程里触发。该属性对应的值为一个长整型,单位是毫秒 示例代码: rule "rule1" duration 3000 when eval(true) then System.out.println("rule thread id:"+Thread.currentThread().getId()); end 8.lock-on-active 做用是 no-loop 的加强版属性,它主要做用在使用 ruleflow-group 属性或 agenda-group 属性的时候。lock-on-active 属性默认值为 false。 9.activation-group 做用是将若干个规则划分红一个组,用一个字符串来给这个组命名,这样在执行的时候,具备相同 activation-group 属性的规则中只要有一个会被执行,其它的规则都将再也不执行。 也就是说,在一组具备相同 activation-group 属性的规则当中,只有一个规则会被执行,其它规则都将不会被执行。固然对于具备相同 activation-group 属性的规则当中究竟哪个会先执行,则能够用相似 salience 之类属性来实现。 示例代码: rule "rule1" activation-group "test" when eval(true) then System.out.println("rule1 execute"); end rule "rule 2" activation-group "test" when eval(true) then System.out.println("rule2 execute"); end 10.agenda-group 做用是agenda-group 属性的值也是一个字符串,经过这个字符串,能够将规则分为若干个Agenda Group,默认状况下,引擎在调用这些设置了 agenda-group 属性的规则的时候须要显 示的指定某个 Agenda Group 获得 Focus (焦点) , 这样位于该 Agenda Group 当中的规则才会触发执行,不然将不执行。 示例代码: rule "rule1" agenda-group "001" when eval(true) then System.out.println("rule1 execute"); end rule "rule 2" agenda-group "002" when eval(true) then System.out.println("rule2 execute"); end java调用: StatefulKnowledgeSession statefulSession = knowledgeBase.newStatefulKnowledgeSession(); statefulSession.getAgenda().getAgendaGroup("002").setFocus(); //得到执行焦点 statefulSession.fireAllRules(); statefulSession.dispose(); //了解便可 不经常使用 11.auto-focus 做用是用来在已设置了 agenda-group 的规则上设置该规则是否能够自动独取 Focus,若是该属性设置为 true,那么在引擎执行时,就不须要显示的为某个 Agenda Group 设置 Focus,不然须要。 12.ruleflow-group 做用是用来将规则划分为一个个的组,而后在规则流当中经过使用 ruleflow-group 属性的值,从而使用对应的规则。

相关文章
相关标签/搜索