drools语法介绍

这里没有翻译http://docs.jboss.org/drools/release/6.4.0.Final/drools-docs/html_single/index.html上的内容 而是参考了网上的一些博客,讲的很详细。摘录了一篇比较好的文章。html

具体的使用例子见后面的wiki:java

开始语法以前首先要了解一下drools的基本工做过程,一般而言咱们使用一个接口来作事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是同样的,咱们须要传递进去数据,用于规则的检查,调用外部接口,同时还可能须要获取到规则执行完毕后获得的结果。在drools中,这个传递数据进去的对象,术语叫 Fact对象。Fact对象是一个普通的java bean,规则中能够对当前的对象进行任何的读写操做,调用该对象提供的方法,当一个java bean插入到workingMemory中,规则使用的是原有对象的引用,规则经过对fact对象的读写,实现对应用数据的读写,对于其中的属性,须要提供getter setter访问器,规则中,能够动态的往当前workingMemory中插入删除新的fact对象。正则表达式

规则文件可使用 .drl文件,也能够是xml文件,这里咱们使用drl文件。数据库

规则语法:api

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行。特别的是,package的名字是随意的,没必要必须对应物理路径,跟java的package的概念不一样,这里只是逻辑上的一种区分。一样的package下定义的function和query等能够直接使用。app

好比:package com.drools.demo.pointoop

import:导入规则文件须要使用到的外部变量,这里的使用方法跟java相同,可是不一样于java的是,这里的import导入的不只仅能够是一个类,也能够是这个类中的某一个可访问的静态方法。post

好比:.net

import com.drools.demo.point.PointDomain;翻译

import com.drools.demo.point.PointDomain.getById;

rule:定义一个规则。rule "ruleName"。一个规则能够包含三个部分:

属性部分:定义当前规则执行的一些属性等,好比是否可被重复执行、过时时间、生效时间等。

条件部分,即LHS,定义当前规则的条件,如  when Message(); 判断当前workingMemory中是否存在Message对象。

结果部分,即RHS,这里能够写普通java代码,即当前规则条件知足后执行的操做,能够直接调用Fact对象的方法来操做应用。

规则事例:

rule "name"

       no-loop true

       when

               $message:Message(status == 0)

       then

               System.out.println("fit");

               $message.setStatus(1);

               update($message);

end

上述的属性中:

no-loop : 定义当前的规则是否不容许屡次循环执行,默认是false,也就是当前的规则只要知足条件,能够无限次执行。什么状况下会出现一条规则执行过一次又被屡次重复执行呢?drools提供了一些api,能够对当前传入workingMemory中的Fact对象进行修改或者个数的增减,好比上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操做会触发规则的从新匹配执行,能够理解为Fact对象更新了,因此规则须要从新匹配一遍,那么疑问是以前规则执行过而且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update以后,以前的修改都会生效。固然对Fact对象数据的修改并非必定须要调用update才能够生效,简单的使用set方法设置就能够完成,这里相似于java的引用调用,因此什么时候使用update是一个须要仔细考虑的问题,一旦不慎,极有可能会形成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,若是自己的RHS部分有update等触发规则从新执行的操做,也不要再次执行当前规则。

可是其余的规则会被从新执行,岂不是也会有可能形成屡次重复执行,数据紊乱甚至死循环?答案是使用其余的标签限制,也是能够控制的:lock-on-active true

lock-on-active true:经过这个标签,能够控制当前的规则只会被执行一次,由于一个规则的重复执行不必定是自己触发的,也多是其余规则触发的,因此这个是no-loop的增强版。固然该标签正规的用法会有其余的标签的配合,后续说起。

date-expires:设置规则的过时时间,默认的时间格式:“日-月-年”,中英文格式相同,可是写法要用各自对应的语言,好比中文:"29-七月-2010",可是仍是推荐使用更为精确和习惯的格式,这须要手动在java代码中设置当前系统的时间格式,后续说起。属性用法举例:date-expires "2011-01-31 23:59:59" // 这里咱们使用了更为习惯的时间格式

date-effective:设置规则的生效时间,时间格式同上。

duration:规则定时,duration 3000   3秒后执行规则

salience:优先级,数值越大越先执行,这个能够控制规则的执行顺序。

其余的属性能够参照相关的api文档查看具体用法,此处略。

 

规则的条件部分,即LHS部分:

when:规则条件开始。条件能够单个,也能够多个,多个条件一次排列,好比

 when

         eval(true)

         $customer:Customer()

         $message:Message(status==0)

上述罗列了三个条件,当前规则只有在这三个条件都匹配的时候才会执行RHS部分,三个条件中第一个

eval(true):是一个默认的api,true 无条件执行,相似于 while(true)

$message:Message(status==0) 这句话标示的:当前的workingMemory存在Message类型而且status属性的值为0的Fact对象,这个对象一般是经过外部java代码插入或者本身在前面已经执行的规则的RHS部分中insert进去的。

前面的$message表明着当前条件的引用变量,在后续的条件部分和RHS部分中,可使用当前的变量去引用符合条件的FACT对象,修改属性或者调用方法等。可选,若是不须要使用,则能够不写。

条件能够有组合,好比:

Message(status==0 || (status > 1 && status <=100))

RHS中对Fact对象private属性的操做必须使用getter和setter方法,而RHS中则必需要直接用.的方法去使用,好比

  $order:Order(name=="qu")
  $message:Message(status==0 && orders contains $order && $order.name=="qu")

特别的是,若是条件所有是 &&关系,可使用“,”来替代,可是二者不能混用

若是如今Fact对象中有一个List,须要判断条件,如何判断呢?

看一个例子:

Message {

        int status;

        List<String> names;

}

$message:Message(status==0 && names contains "网易" && names.size >= 1)

上述的条件中,status必须是0,而且names列表中含有“网易”而且列表长度大于等于1

contains:对比是否包含操做,操做的被包含目标能够是一个复杂对象也能够是一个简单的值。 

Drools提供了十二中类型比较操做符:

>  >=  <  <=  ==  !=  contains / not contains / memberOf / not memberOf /matches/ not matches

not contains:与contains相反。

memberOf:判断某个Fact属性值是否在某个集合中,与contains不一样的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象。

not memberOf:正好相反。

matches:正则表达式匹配,与java不一样的是,不用考虑'/'的转义问题

not matches:正好相反。

 

规则的结果部分

当规则条件知足,则进入规则结果部分执行,结果部分能够是纯java代码,好比:

then

       System.out.println("OK"); //会在控制台打印出ok

end

固然也能够调用Fact的方法,好比  $message.execute();操做数据库等等一切操做。

结果部分也有drools提供的方法:

insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定;

update:更新

modify:修改,与update语法不一样,结果都是更新操做

retract:删除

RHS部分除了调用Drools提供的api和Fact对象的方法,也能够调用规则文件中定义的方法,方法的定义使用 function 关键字

function void console {

   System.out.println();

   StringUtils.getId();// 调用外部静态方法,StringUtils必须使用import导入,getId()必须是静态方法

}

Drools还有一个能够定义类的关键字:

declare 能够再规则文件中定义一个class,使用起来跟普通java对象类似,你能够在RHS部分中new一个而且使用getter和setter方法去操做其属性。

declare Address
 @author(quzishen) // 元数据,仅用于描述信息

 @createTime(2011-1-24)
 city : String @maxLengh(100)
 postno : int
end

上述的'@'是什么呢?是元数据定义,用于描述数据的数据~,没什么执行含义

你能够在RHS部分中使用Address address = new Address()的方法来定义一个对象。

其余参考:

相关文章
相关标签/搜索