drools規則語言指南(五)規則條件和行爲

DRL中的規則條件(WHEN,LHS)

規則結構

image

規則中的條件

image
DRL中的when部分就是規則的條件(一般又叫作規則的左手邊,即:Left Hand Side(LHS)
只有知足了全部的條件,纔回去執行then部分,若是when部分爲空,就是沒有條件,那麼就默認爲true,下面是一個空條件的例子:html

rule "Always insert applicant"
  when
    // Empty
  then   // Actions to be executed once
    insert( new Applicant() );
end

// 規則在引擎內部會變成以下這樣:

rule "Always insert applicant"
  when
    eval( true )
  then
    insert( new Applicant() );
end

若是條件之間沒有連詞的話(如:and,or,not),默認的就是and,就是同時知足全部條件java

rule "Underage"
  when
    application : LoanApplication()
    Applicant( age < 21 )
  then
    // Actions
end

// 在規則引擎內部是下面這樣,加上個and:

rule "Underage"
  when
    application : LoanApplication()
    and Applicant( age < 21 )
  then
    // Actions
end

模式和約束

在規則的條件中定義模式並由規則去匹配,一個模式能夠匹配每個被插入到working memory中的fact,同時模式也能夠增長約束去限制哪些fact會被匹配上
image
舉個沒有約束的例子,下面定的這個模式,能夠匹配全部插入到WM中的Person對象。正則表達式

Person()

這個類型不須要是一個真是的class,能夠是父類甚至是接口,好比下面這個例子就會匹配WM中全部的對象算法

Object() // Matches all objects in the working memory

增長了約束的模式,限制了age等於50express

Person( age == 50 )

約束是一個會返回true或false的表達式,和java很像,可是有所加強,能夠直接經過屬性名訪問屬性segmentfault

Person( age == 50 )

// 這二者是同樣的

Person( getAge() == 50 )

若是約束的值類型和屬性的類型不一致,那麼drools內部會自動作強制類型轉換,若是轉不了就會報錯,好比:app

Person( age == "10" ) // "10" 強制轉爲 10

多個約束:dom

// Person is at least 50 years old and weighs at least 80 kilograms:
Person( age > 50, weight > 80 )

// Person is at least 50 years old, weighs at least 80 kilograms, and is taller than 2 meters:
Person( age > 50, weight > 80, height > 2 )

也可使用&&和||,可是不能夠和","混用ide

// 不能用:
Person( ( age > 50, weight > 80 ) || height > 2 )

// 應該這樣用:
Person( ( age > 50 && weight > 80 ) || height > 2 )

在模式和約束中綁定變量

使用$變量名這種形式來綁定變量:spa

rule "simple rule"
when
    $p : Person()
then
    System.out.println( "Person " + $p );
end

注意:

// 不能這樣用:
Person( $age : age * 2 < 100 )

// 要這樣用:
Person( age * 2 < 100, $age : age )

嵌套約束和內聯強制轉換

嵌套約束的使用:

Person( name == "mark", address.city == "london", address.country == "uk" )
//或者寫成:
Person( name == "mark", address.( city == "london", country == "uk") )

內聯強制轉換:

// Inline casting with subtype name:
Person( name == "mark", address#LongAddress.country == "uk" )

// Inline casting with fully qualified class name:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )

// Multiple inline casts:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )

使用instanceof進行類型判斷

Person( name == "mark", address instanceof LongAddress, address.country == "uk" )

日期約束

默認的日期格式是dd-mm-yyyy,你也能夠自定義格式經過系統屬性drools.dateformat="dd-mm-yyyy hh:mm"

Person( bornBefore < "27-Oct-2009" )

DRL特有的操做符

DRL支持標準的java語法,可是有些操做符是DRL所獨有的,好比:.(),#,經過前者去分組獲取屬性值,經過後者強制類型轉換成子類型

// Ungrouped property accessors:
Person( name == "mark", address.city == "london", address.country == "uk" )

// Grouped property accessors:
Person( name == "mark", address.( city == "london", country == "uk") )
// Inline casting with subtype name:
Person( name == "mark", address#LongAddress.country == "uk" )

// Inline casting with fully qualified class name:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )

// Multiple inline casts:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )

!. 操做符至關於!=null

Person( $streetName : address!.street )

// This is internally rewritten in the following way:

Person( address != null, $streetName : address.street )

[ ] 獲取list或map的值

// The following format is the same as `childList(0).getAge() == 18`:
Person(childList[0].age == 18)

// The following format is the same as `credentialMap.get("jdoe").isValid()`:
Person(credentialMap["jdoe"].valid)

matches , not matches 正則匹配,與java中使用正則表達式相同

Person( country matches "(USA)?\\S*UK" )

Person( country not matches "(USA)?\\S*UK" )

contains , not contains 判斷值是否在Array或Collection中

// Collection with a specified field:
FamilyTree( countries contains "UK" )

FamilyTree( countries not contains "UK" )


// Collection with a variable:
FamilyTree( countries contains $var )

FamilyTree( countries not contains $var )

一樣能夠用於字符串的包含,至關於String.contains(),!String.contains()

// Sting literal with a specified field:
Person( fullName contains "Jr" )

Person( fullName not contains "Jr" )


// String literal with a variable:
Person( fullName contains $var )

Person( fullName not contains $var )

memberOf , not memberOf 判斷字段值是否在Array或Collection中,它們必須是 變量

FamilyTree( person memberOf $europeanDescendants )

FamilyTree( person not memberOf $europeanDescendants )

soundslike 英語發音類似,使用 Soundex algorithm算法判斷(nubility)

// Match firstName "Jon" or "John":
Person( firstName soundslike "John" )

str 判斷一個字符串是否已指定值開頭、結尾、以及長度是多少

// Verify what the String starts with:
Message( routingValue str[startsWith] "R1" )

// Verify what the String ends with:
Message( routingValue str[endsWith] "R2" )

// Verify the length of the String:
Message( routingValue str[length] 17 )

in , not in

Person( $color : favoriteColor )
Color( type in ( "red", "blue", $color ) )

Person( $color : favoriteColor )
Color( type notin ( "red", "blue", $color ) )

還有不少其餘的操做符合關鍵字能夠參考這個

DRL中的規則行爲(THEN)

DRL中的then部分就是規則觸發後的行爲(規則的右手邊Right Hand Side (RHS) ),基本上能夠概況爲向working memory中 insert、delete、或modify數據。

rule "Underage"
  when
    application : LoanApplication()
    Applicant( age < 21 )
  then
    application.setApproved( false );
    application.setExplanation( "Underage" );
end
DRL中支持的行爲

set 設置字段值,和java相同

set<field> ( <value> )

例:

$application.setApproved ( false );
$application.setExplanation( "has been bankrupt" );

modify 修改對象並告知engine

modify ( <fact-expression> ) {
    <expression>,
    <expression>,
    ...
}

例:

modify( LoanApplication ) {
        setAmount( 100 ),
        setApproved ( true )
}

update 更新對象並告知engine

update ( <object, <handle> )  // Informs the Drools engine that an object has changed

update ( <object> )  // Causes `KieSession` to search for a fact handle of the object

例:

LoanApplication.setAmount( 100 );
update( LoanApplication );

能夠看出,咱們能夠用modify來代替,可是update提供了額外的監聽器,來監聽屬性值的變化,屬性監聽器

insert 插入一個新的fact

//用法:
insert( new <object> );
//例:
insert( new Applicant() );

insertLogical 邏輯插入一個新的fact,drools engine負責這個fact的建立和回收,當建立這個fact的條件爲false時,這個fact就會被engine自動回收掉

//用法:
insertLogical( new <object> );
//例:
insertLogical( new Applicant() );

delete 刪除一個對象,retract也能夠,可是建議使用delete

//用法
delete( <object> );
//例:
delete( Applicant );

註釋

和java中的註釋相同

rule "Underage"
  // This is a single-line comment.
  when
    $application : LoanApplication()  // This is an in-line comment.
    Applicant( age < 21 )
  then
    /* This is a multi-line comment
    in the rule actions. */
    $application.setApproved( false );
    $application.setExplanation( "Underage" );
end

DRL中的錯誤信息

若是規則有問題,會按照以下格式輸出
image

  • 1st Block: 錯誤碼
  • 2nd Block: 源碼中出現錯誤的位置在多少行
  • 3rd Block: 問題描述
  • 4th Block: 錯誤在源碼的哪一個部分
  • 5th Block: 源碼的哪一個模式出錯誤了
相關文章
相關標籤/搜索