文章目錄
- 1.DRL文件的組成:
- 2.package
- 3.import
- 4.function
- 5.query
- 6.declare
- 7.global
- 8.rule
- 8.1.規則屬性
- 8.2.LHS
- 8.2.1.語法格式
- 8.2.2.運算符優先級
- 8.2.3.特殊的運算符
- 1.`matches`, `not matches`
- 2.`contains`, `not contains`
- 3.`memberOf`, `not memberOf`
- 4.`in`, `notin`
- 5.`soundslike`
- 6.`str`
- 7.`from`
- 8.3.RHS
- 8.3.1.`set`
- 8.3.2.`modify`
- 8.3.3.`update`
- 8.3.4.`insert`
- 8.3.5.`delete`
- 8.3.6.`drools.halt()`
1.DRL文件的組成:
在官方文檔中(鏈接地址 https://docs.drools.org/7.74.1.Final/drools-docs/html_single/index.html#_droolslanguagereferencechapter),DRL的組成如下:
packageimportfunction // Optionalquery // Optionaldeclare // Optionalglobal // Optionalrule "rule name"// Attributeswhen// Conditionsthen// Actions
endrule "rule2 name"...
以上內容,只是梳理了DRL文件中組成的元素及其順序(順序非強制性要求,這是這樣便于內容閱讀)。
2.package
類似于 Java
中的 package
,聲明規則的唯一命名空間(包)。包必須有一個名稱空間,并使用包名稱的標準 Java
約定進行聲明;即沒有空格,這與允許空格的規則名稱不同。根據元素的順序,它們可以以任何順序出現在規則文件中,但package
語句除外,它必須位于文件的頂部。在任何情況下,分號都是可選的。
任何規則屬性(見“規則屬性”一節)也可以在包級別編寫,取代該屬性的默認值。修改后的默認值仍可能被規則中的屬性設置所替換。
示例
// 帶分號
package com.test;
// 不帶分號
package com.test
3.import
類似于 Java
中的 import
。DRL文件中在規則中需要導入使用的對象的完全限定路徑和類型名稱。Drools引擎自動從與DRL包同名的Java
包和Java.lang
包中導入類。
示例
// 不需要導入,已自動導入
// import java.lang.String;import com.a.b.DroolsObject;
4.function
類似于 Java
中的 method
。可以將重復代碼或者邏輯性代碼封裝成一個函數,或者將工具/輔助類中的靜態方法導入為函數,然后在規則LHS/RHS部分中按名稱使用該函數。
示例
// 導入靜態方法/函數
import static org.example.applicant.MyFunctions.hello;// 函數1
function boolean ageJudge(Integer i){if (i > 10){return true;} else {return false;}
}// 使用函數
rule "age"
enabled true
wheneval(ageJudge(10));
then
end
5.query
查詢在工作內存中相關的事實對象。查詢的名稱對于 KieBase
是全局的,因此對于該項目中的所有其他規則的查詢必須是唯一的。ksession.getQueryResults("name")
獲取查詢結果,其中“name”是查詢名稱。
示例
package drools.drl// 導入輸入類型
import com.ahao.project.input.UserIn;
global com.ahao.project.output.UserOut output;query "age>10"$in:UserIn(age > 10)
end
獲取結果
QueryResults queryResults = kieSession.getQueryResults("age>10");
Iterator<QueryResultsRow> iterator = queryResults.iterator();
while (iterator.hasNext()) {QueryResultsRow next = iterator.next();log.info("查詢結果:{}",next.get("$in"));
}// [main] INFO DroolsTest2 - 查詢結果:UserIn(age=35)
// [main] INFO DroolsTest2 - 查詢結果:UserIn(age=45)
6.declare
聲明類型。用于在DRL聲明一個新的類型。
示例
package drools.drlimport com.ahao.project.input.UserIn// 聲明一個Person類型
declare Personname:Stringage:Integer
endrule "age"
enabled true
when$in:UserIn(age > 10)
thenPerson person = new Person();person.setAge($in.getAge());person.setName("命中規則");System.out.println(person);
end
結果
7.global
全局變量。DRL文件中的全局變量通常為規則提供數據或服務,如在then中使用的應用程序服務(service),并從規則返回數據。
示例
// 全局變量的定義
global com.ahao.project.output.UserOut output;
// 可以有多個
// global com.ahao.project.output.UserOut output222;
注意:
執行規則時,需要先設置全局變量對象
kieSession.setGlobal("output", output); // 然后再 kieSession.fireAllRules()
8.rule
rule語法結構如下圖
8.1.規則屬性
屬性 | 默認值 | 描述 |
---|---|---|
salience | 0 | 規則優先級。在同一個 activation-group 中,具有較高優先級(值越大)的規則優先執行 示例: salience 10 |
enabled | true | 是否啟用該規則 示例: enabled true |
date-effective | null | 只有當前日期時間在 date-effective 屬性之后時,才能激活該規則 示例: date-effective "4-Sep-2018" |
date-expires | null | 只有當前日期時間在 date-expires 屬性之前時,才能激活該規則 示例: date-expires "4-Oct-2018" |
no-loop | false | 是否可循環。某些情況下(update函數等),規則可以被再次激活 示例: no-loop true |
agenda-group | default | 議程組。對議程進行分區,以提供對規則組的更多執行控制。只有獲得焦點的議程組中的規則才能被激活。 示例: agenda-group "GroupName" |
activation-group | null | 激活組。一個激活組只能激活一個規則,即使其他規則體的LHS部分仍然為true也不會再被執行。 示例: activation-group "GroupName" |
duration | null | 以毫秒為單位的持續時間。如果規則條件當前滿足,則在該持續時間之后可以激活規則。 示例: duration 10000 |
timer | null | 調度器。“時間間隔”或“cron”計時器定義 示例: timer ( cron:* 0/15 * * * ? ) (every 15 minutes) |
calendar | null | 用于調度規則的 Quartz calendar 示例: calendars "* * 0-7,18-23 ? * *" (exclude non-business hours) |
auto-focus | false | 自動獲取焦點,僅適用于議程組內的規則。選擇該選項后,下次激活規則時,會自動將焦點指定給規則所分配的議程組: 示例: auto-focus true |
lock-on-active | false | 僅適用于規則流組或議程組內的規則。選擇該選項后,下次規則的規則流組變為活動狀態或規則的議程組收到焦點時,在規則流組不再活動或議程組失去焦點之前,無法再次激活規則。是no-loop屬性的更強版本。 示例: lock-on-active true |
ruleflow-group | null | 規則流組。只有被關聯的規則流激活這個組時,規則才能激活 示例: ruleflow-group "GroupName" |
dialect | mvel | 用來定義規則中要使用的語言類型 示例: dialect "java" |
8.2.LHS
規則的when部分(也稱為Left Hand Side(LHS))包含執行操作必須滿足的條件。
8.2.1.語法格式
格式
// 格式如下(對象名稱前的 $ 非必需的)
when$對象名稱:事實對象的全限定類名(字段約束)// 如果已經import了事實對象的全限定類名
when$對象名稱:事實對象的類名(字段約束)
示例
// 示例1
when$p:com.test.Person(age > 10 || name == "jack")// 示例2
import com.test.Person;
whenp:Person(age > 10 || name == "jack")
8.2.2.運算符優先級
操作類型 | 符號 | Notes |
---|---|---|
嵌套或(null-safe)屬性訪問 | . , .() , !. | 不是標準的Java語義 |
List 或者 Map 訪問 | [] | 不是標準的Java語義 |
約束綁定(類型綁定) | : | 不是標準的Java語義 |
乘積 | * , / ,% | |
加減 | + , - | |
位運算 | >> , >>> , << | |
關系型 | < , <= , > , >= , instanceof | |
等于 | == != | 使用equals() 和!equals() 語義,非標準Java same 和not same 語義 |
非短路 AND | & | |
非短路異運算 | ^ | |
非短路包含 OR | ` | ` |
邏輯運算 AND | && | |
邏輯運算 OR | ` | |
三元運算符 | ? : | |
逗號分隔 AND | , | 不是標準的Java語義 |
運算符
==
使用null-safe equals()
語義,而不是通常的equals
語義。例如,Person(firstName=="John")
類似于java.util。Objects.equals(person.getFirstName(),“John”)
,并且由于"John"
不為null
,所以該模式也類似于"John".equals(person.get-FirstName)
。
以上運算符都基本上類似java中的運算符。接下會介紹一些特殊的運算符。
8.2.3.特殊的運算符
1.matches
, not matches
判斷與指定的Java正則表達式匹配或不匹配。
示例
Person( country matches "(USA)?\\S*UK" )
2.contains
, not contains
數組或集合字段是否包含指定值。可以使用這些運算符來代替String.contains()和!String.contents()。
示例
// 姓名包含王
Person( name contains "王" )
// 假設一個人有多個手機號,phones:List<String>
// 手機號不包含12345678901
Person( phones not contains "12345678901" )
3.memberOf
, not memberOf
是否為數組或集合的成員。
示例
// 手機號不包含12345678901
Person( "12345678901" not memberOf phones)
4.in
, notin
指定約束中要匹配的多個可能值(復合值限制)。
示例
// 名稱為 jack 或者 mary
Person( name in ("jack","mary"))
5.soundslike
驗證單詞是否具有與給定值幾乎相同的發音(英語發音)。
示例
// firstName "Jon" or "John":
Person( firstName soundslike "John" )
6.str
驗證字符串字段是以指定值開始,以指定值結束,或者字符串的長度。
示例
// 消息的以"R1"開始
Message( msg str[startsWith] "R1" )// 消息的以"R2"結尾
Message( msg str[endsWith] "R2" )// 消息的長度為17
Message( msg str[length] 17 )
7.from
獲取數據源。
示例
// 從模式綁定(變量)中獲取數據源
rule "rule1"
whenPerson( $personAddress : address )Address( zipcode == "11110" ) from $personAddress
then
end// 從圖形符號中獲取數據源
rule "rule1"
when$p : Person()$a : Address( zipcode == "23920W" ) from $p.address
then
end// 從迭代器中獲取數據源
rule "rule1"
when$order : Order()$item : OrderItem( value > 100 ) from $order.items
then
end
8.3.RHS
規則的then部分(也稱為 Right Hand Side(RHS))。當滿足規則的when部分時要執行的操作。操作的主要目的是在Drools引擎的工作內存中插入、刪除或修改數據。有效的規則操作是小的、聲明性的和可讀的。如果需要在規則操作中使用命令式或條件式代碼,請將規則劃分為多個更小、更具聲明性的規則。
8.3.1.set
賦值。
示例
$person.setName("jack");
8.3.2.modify
針對某個事實進行修改,并將更改通知Drools引擎。
語法
modify ( <fact-expression> ) {<expression>,<expression>,...
}
示例
modify( Person ) {setAge( 100 ),setName ( "nick" )
}
8.3.3.update
指定要更新的字段和整個相關事實,并將更改通知Drools引擎。
語法
update ( <object, <handle> )
update ( <object> )
示例
person.setAge( 100 );
update( person );
8.3.4.insert
將一個新的事實插入Drools引擎的工作內存中。
語法
insert( new <object> );
示例
insert( new Person() );
8.3.5.delete
從Drools引擎中刪除對象。
語法
delete( <object> );
示例
delete( person );
8.3.6.drools.halt()
終止規則執行。
示例
rule "end_rule"
enabled true
when
thendrools.halt();
end