Drools語法-Language
關(guān)鍵詞
Pakage
-
package
package表示一個命名空間.package是必須定義的,必須放在規(guī)則文件第一行. -
import
import語句的工作方式類似于Java中的import語句。您需要為要在規(guī)則中使用的任何對象指定完全限定路徑和類型名稱。 -
global
global用于定義全局變量。Rules:
global java.util.List myGlobalList; rule "Using a global" when eval( true ) then myGlobalList.add( "Hello World" ); endSet the global value:
List list = new ArrayList(); KieSession kieSession = kiebase.newKieSession(); kieSession.setGlobal( "myGlobalList", list );
Function
-
function
function是一種將語義代碼放置在規(guī)則源文件中的方法,而不是普通的Java類function String hello(String name) { return "Hello "+name+"!"; } import function my.package.Foo.hello rule "using a static function" when eval( true ) then System.out.println( hello( "Bob" ) ); end
Query
-
query
query是一種搜索工作內(nèi)存中與指定條件匹配的事實的簡單方法.對所有30歲以上的人的簡單查詢 query "people over the age of 30" person : Person( age > 30 ) end 查詢超過x歲的人,以及居住在y的人 query "people over the age of x" (int x, String y) person : Person( age > x, location == y ) end QueryResults results = ksession.getQueryResults( "people over the age of 30" ); System.out.println( "we have " + results.size() + " people over the age of 30" ); System.out.println( "These people are are over 30:" ); for ( QueryResultsRow row : results ) { Person person = ( Person ) row.get( "person" ); System.out.println( person.getName() + "\n" ); }
Rule
rule定義規(guī)則。rule "ruleName"。
一個規(guī)則可以包含三個部分:屬性部分,條件部分:即LHS,結(jié)果部分:即RHS.

屬性部分-Attributes
定義當(dāng)前規(guī)則執(zhí)行的一些屬性等,比如是否可被重復(fù)執(zhí)行、過期時間、生效時間等。
activation-group agenda-group auto-focus date-effective date-expires dialect duration duration-value enabled lock-on-active no-loop ruleflow-group salience
[圖片上傳失敗...(image-26f804-1526628115111)]
-
no-loop
默認(rèn)值:false
類型:Boolean
在一個規(guī)則當(dāng)中如果條件滿足就對
Working Memory當(dāng)中的某個Fact對象進(jìn)行了修改,比如使用update 將其更新到當(dāng)前的Working Memory當(dāng)中,這時引擎會再次檢查所有的規(guī)則是否滿足條件,如果滿足會再次執(zhí)行. -
ruleflow-group
默認(rèn)值:N/A
類型:String
Ruleflow是一個Drools功能,可讓您控制規(guī)則的觸發(fā)。由相同的規(guī)則流組標(biāo)識匯編的規(guī)則僅在其組處于活動狀態(tài)時觸發(fā)。將規(guī)則劃分為一個個的組,然后在規(guī)則流當(dāng)中通過使用ruleflow-group屬性的值,從而使用對應(yīng)的規(guī)則。 -
lock-on-active
默認(rèn)值:false
類型:Boolean
當(dāng)在規(guī)則上使用
ruleflow-group屬性或agenda-group屬性的時候,將lock-on-action屬性的值設(shè)置為true,可能避免因某些Fact 對象被修改而使已經(jīng)執(zhí)行過的規(guī)則再次被激活執(zhí)行。可以看出該屬性與no-loop屬性有相似之處,no-loop屬性是為了避免Fact 修改或調(diào)用了insert、retract、update之類而導(dǎo)致規(guī)則再次激活執(zhí)行,這里的lock-on-action屬性也是起這個作用,lock-on-active是no-loop的增強(qiáng)版屬性,它主要作用在使用ruleflow-group屬性或agenda-group屬性的時候 -
salience
默認(rèn)值:0
類型:integer
設(shè)置規(guī)則執(zhí)行的優(yōu)先級,
salience屬性的值是一個數(shù)字,數(shù)字越大執(zhí)行優(yōu)先級越高,同時它的值可以是一個負(fù)數(shù).
規(guī)則的salience默認(rèn)值為0,所以如果我們不手動設(shè)置規(guī)則的salience屬性,那么它的執(zhí)行順序是隨機(jī)的. -
agenda-group
默認(rèn)值:MAIN
類型:String
規(guī)則的調(diào)用與執(zhí)行是通過
StatelessSession或StatefulSession來實現(xiàn)的,一般的順序是創(chuàng)建一個StatelessSession或StatefulSession,將各種經(jīng)過編譯的規(guī)則的package 添加到session當(dāng)中,接下來將規(guī)則當(dāng)中可能用到的Global對象和Fact對象插入到Session 當(dāng)中,最后調(diào)用fireAllRules 方法來觸發(fā)、執(zhí)行規(guī)則。在沒有調(diào)用最后一步fireAllRules方法之前,所有的規(guī)則及插入的Fact對象都存放在一個名叫Agenda表的對象當(dāng)中,這個Agenda表中每一個規(guī)則及與其匹配相關(guān)業(yè)務(wù)數(shù)據(jù)叫做Activation,在調(diào)用fireAllRules方法后,這些Activation 會依次執(zhí)行,這些位于Agenda 表中的Activation 的執(zhí)行順序在沒有設(shè)置相關(guān)用來控制順序的屬性時(比如salience 屬性),它的執(zhí)行順序是隨機(jī)的,不確定的。Agenda Group是用來在Agenda 的基礎(chǔ)之上,對現(xiàn)在的規(guī)則進(jìn)行再次分組,具體的分組方法可以采用為規(guī)則添加agenda-group屬性來實現(xiàn)。agenda-group屬性的值也是一個字符串,通過這個字符串,可以將規(guī)則分為若干個Agenda Group,默認(rèn)情況下,引擎在調(diào)用這些設(shè)置了agenda-group屬性的規(guī)則的時候需要顯示的指定某個Agenda Group得到Focus(焦點),這樣位于該Agenda Group當(dāng)中的規(guī)則才會觸發(fā)執(zhí)行,否則將不執(zhí)行。 -
auto-focus
默認(rèn)值:false
類型:Boolean
用來在已設(shè)置了
agenda-group的規(guī)則上設(shè)置該規(guī)則是否可以自動獨取Focus,如果該屬性設(shè)置為true,那么在引擎執(zhí)行時,就不需要顯示的為某個Agenda Group設(shè)置Focus,否則需要。對于規(guī)則的執(zhí)行的控制,還可以使用Agenda Filter來實現(xiàn)。在Drools 當(dāng)中,提供了一個名為org.drools.runtime.rule.AgendaFilter 的Agenda Filter接口,用戶可以實現(xiàn)該接口,通過規(guī)則當(dāng)中的某些屬性來控制規(guī)則要不要執(zhí)行。org.drools.runtime.rule.AgendaFilter接口只有一個方法需要實現(xiàn),方法體如下:public boolean accept(Activation activation);在該方法當(dāng)中提供了一個Activation參數(shù),通過該參數(shù)我們可以得到當(dāng)前正在執(zhí)行的規(guī)則對象或其它一些屬性,該方法要返回一個布爾值,該布爾值就決定了要不要執(zhí)行當(dāng)前這個規(guī)則,返回true 就執(zhí)行規(guī)則,否則就不執(zhí)行。 -
activation-group
默認(rèn)值:N/A
類型:String
該屬性的作用是將若干個規(guī)則劃分成一個組,用一個字符串來給這個組命名,這樣在執(zhí)行的時候,具有相同
activation-group屬性的規(guī)則中只要有一個會被執(zhí)行,其它的規(guī)則都將不再執(zhí)行。也就是說,在一組具有相同activation-group屬性的規(guī)則當(dāng)中,只有一個規(guī)則會被執(zhí)行,其它規(guī)則都將不會被執(zhí)行。當(dāng)然對于具有相同activation-group屬性的規(guī)則當(dāng)中究竟哪一個會先執(zhí)行,則可以用類似salience之類屬性來實現(xiàn)。 -
dialect
默認(rèn)值: 根據(jù)package指定
類型:String,"java" or "mvel"
dialect種類是用于LHS或RHS代碼塊中的任何代碼表達(dá)式的語言。目前有兩種dialect,Java和MVEL。雖然dialect可以在包級別指定,但此屬性允許為規(guī)則覆蓋包定義。 -
date-effective
默認(rèn)值:N/A
類型:字符串,包含日期和時間定義。格式:
dd-MMM-yyyy(25-Sep-2009).僅當(dāng)當(dāng)前日期和時間在日期有效屬性后面時,才能激活規(guī)則。
-
date-expires
默認(rèn)值:N/A
類型:字符串,包含日期和時間定義。格式:
dd-MMM-yyyy(25-Sep-2009).如果當(dāng)前日期和時間在
date-expires屬性之后,則無法激活規(guī)則. -
enabled
默認(rèn)值:false
類型:String
表示規(guī)則是可用的,如果手工為一個規(guī)則添加一個
enabled屬性,并且設(shè)置其enabled屬性值為false,那么引擎就不會執(zhí)行該規(guī)則. -
duration
默認(rèn)值:無
類型:long
持續(xù)時間指示規(guī)則將在指定的持續(xù)時間之后觸發(fā),如果它仍然是true.
條件部分-LHS
定義當(dāng)前規(guī)則的條件,如when Message(); 判斷當(dāng)前workingMemory中是否存在Message對象。
Left Hand Side(LHS)是規(guī)則的條件部分的公共名稱。它由零個或多個條件元素組成。
如果LHS為空,它將被認(rèn)為是一個條件元素,它總是為真,并且當(dāng)創(chuàng)建一個新的WorkingMemory會話時,它將被激活一次。
Conditions / LHS —匹配模式(Patterns)
沒有字段約束的Pattern
Person()
有文本字段約束的Pattern
Person( name == “bob” )
字段綁定的Pattern
Person( $name : name == “bob” )
變量名稱可以是任何合法的java變量,$是可選的,可由于區(qū)分字段和變量
Fact綁定的Pattern
$bob : Person( name == “bob” )字段綁定的Pattern
變量約束的Pattern
Person( name == $name )
Drools提供了十二種類型比較操作符:
> >= < <= == != contains not contains memberOf not memberOf matches not matches
-
contains
運算符
contains用于檢查作為Collection或elements的字段是否包含指定的值.Cheese( name contains "tilto" ) Person( fullName contains "Jr" ) String( this contains "foo" ) -
not contains
和
contains相反 -
memberOf
運算符
memberOf用于檢查字段是否是集合的成員或元素;該集合必須是一個變量。CheeseCounter( cheese memberOf $matureCheeses ) -
not memberOf
和
memberOf相反 -
matches
正則表達(dá)式匹配,與java不同的是,不用考慮'/'的轉(zhuǎn)義問題
Cheese( type matches "(Buffalo)?\\S*Mozarella" ) -
not matches
和
matches相反
其他條件元素:
-
exists
存在。檢查Working Memory是否存在某物。使用模式
exists,則規(guī)則將只激活最多一次,而不管在工作存儲器中存在與存在模式中的條件匹配的數(shù)據(jù)量 -
not
不存在,檢查工作存儲器中是否存在某物。認(rèn)為“
not”意味著“there must be none of...”。
結(jié)果部分-RHS
這里可以寫普通java代碼,即當(dāng)前規(guī)則條件滿足后執(zhí)行的操作,可以直接調(diào)用Fact對象的方法來操作應(yīng)用。
Right Hand Side(RHS)是規(guī)則的結(jié)果或動作部分的通用名稱;此部分應(yīng)包含要執(zhí)行的操作的列表。在規(guī)則的RHS中使用命令式或條件式代碼是不好的做法;作為一個規(guī)則應(yīng)該是原子的性質(zhì) - “when this, then do this”,而不是“when this, maybe do this”。規(guī)則的RHS部分也應(yīng)該保持較小,從而保持聲明性和可讀性。如果你發(fā)現(xiàn)你需要在RHS中的命令式和/或條件代碼,那么也許你應(yīng)該把這個規(guī)則分成多個規(guī)則。 RHS的主要目的是插入,刪除或修改工作存儲器數(shù)據(jù)。為了協(xié)助,有一些方便的方法可以用來修改工作記憶;而不必首先引用工作內(nèi)存實例。
-
update
更新,告訴引擎對象已經(jīng)改變(已經(jīng)綁定到LHS上的某個東西),并且規(guī)則可能需要重新考慮。
-
insert(new Something())
插入,往當(dāng)前
workingMemory中插入一個新的Fact對象,會觸發(fā)規(guī)則的再次執(zhí)行,除非使用no-loop限定; -
insertLogical(new Something())
類似于
insert,但是當(dāng)沒有更多的facts支持當(dāng)前觸發(fā)規(guī)則的真實性時,對象將被自動刪除。 -
modify
修改,與
update語法不同,結(jié)果都是更新操作。該語言擴(kuò)展提供了一種結(jié)構(gòu)化的方法來更新事實。它將更新操作與一些setter調(diào)用相結(jié)合來更改對象的字段。 -
retract
刪除
一些內(nèi)置的method。
-
drools.halt()
調(diào)用
drools.halt()立即終止規(guī)則執(zhí)行。這是需要將控制權(quán)返回到當(dāng)前會話使用fireUntilHalt()的點。 -
drools.getWorkingMemory()
返回WorkingMemory對象.
-
drools.setFocus( String s)
將焦點設(shè)置為指定的
agenda group. -
drools.getRule().getName()
從規(guī)則的RHS調(diào)用,返回規(guī)則的名稱。
-
drools.getTuple()
返回與當(dāng)前執(zhí)行的規(guī)則匹配的
Tuple,而drools.getActivation()傳遞相應(yīng)的激活。