drools规则语法
1、基本的匹配規則
1.1變量
drools使用匹配的方式對Fact進行比對,
比如
MVEL代碼
account:Account(balance>100)
這個規則的含義就是在Fact中找到類型為Account,且balance屬性值大于100的所有Account實例。
可以指定變量來描述一個類型或者一個映射一個類的屬性,
比如
MVEL代碼
$account:Account($type:type)
使用$Variable來定義一個變量,這里定義了兩個變量,$account表示定義一個類型為Account的變量,而$type映射Account類型中的type屬性。定義變量是為了在后續的規則中使用。
MVEL代碼
$account:Account(balance>100)
Customer(account==$account)
這個就是說要找到一些Custom類型的Fact,且其account屬性必須滿足前面定義的balance>100的條件。
1.2類型
drools支持各種java數據類型
String:字符串
MVEL代碼
Customer(name=="john")
正則表達式:
MVEL代碼
Customer(namematches"[A-Z][a-z]+")
表示Customer類型的name屬性必須滿足首字母為大寫A-Z,且第二位以后有一個或者多個小寫的a-z組成。
Date:日期類型
MVEL代碼
Account(dateCreate>"01-Feb-2009")
日期的格式默認是"dd-mmmm-yyyy",可以更改。
Boolean:布爾類型
MVEL代碼
Transaction(isApprove==true)
Enum:枚舉類型
MVEL代碼
Account(type==Account.Type.STUDENT)
1.3注釋
單行注釋://或者#
多行注釋: /* */
1.4包
MVEL代碼
packagecom.kingsun.drools.rules
聲明該規則文件所屬的包,是一種namespace組織方式,和java的包類似,物理上不需要存在相應的目錄結構,它只是邏輯上的劃分。
1.5導入
import可以導入在規則中使用到的類,也可以導入在規則中使用到的外部定義的functiong
MVEL代碼
importjava.util.Map;
importcom.kingsun.drools.service.LegacyBankService.extractData;
當導入方法時,這個方法必須是static的,因為利用的是jdk1.5的static import特性。
1.6全局變量global
聲明一個global變量
MVEL代碼
globalReportFactoryreportFactory;
給全局變量賦值
MVEL代碼
session.setGlobal("reportFactory",reportFactory);
或者
MVEL代碼
List<Command>commands=newArrayList<Command>();
commmands.add(CommandFactory.newSetGlobal("reportFactory",reportFactory));
使用全局變量
MVEL代碼
session.getGlobals();
1.7函數Functions
function可以在規則文件中定義,但更多的是使用外部類中定義的static方法,這樣只要java中可以實現的邏輯,在規則中都可以做為function調用。
調用外部類的functiong需要注意的是方法必須是靜態的,static,而且這個類可以在Help輔助類中定義。
外部類需要import,此時在function中用到的參數類型也需要import。
如: 在外部的ValidationHelper輔助類中定一個一個static方法
Java代碼
publicstaticdoublecalculateAccount(Accountaccount){
return100+account.balance*1.2;
}
在規則drl文件中可以這么使用:
Drl代碼
importcom.kingsun.drools.domain.Account;
importfunctioncom.kingsun.drools.util.ValidationHelper.calculateAccount;
rule"validationaccount"
when
$account:Account(balance>100)
then
Account(balance==calculateAccount($account));
end
1.8方言dialect
在規則表達式中可以使用方言來簡化表達式,使之更加具有可讀性。
MVEL代碼
packagecom.kingsun.drools.rules;
dialect"mvel"
方言默認的是java,drools也支持mvel,在package的后面聲明該規則文件使用的方言
mvel
mvel是一種基于java應用程序的表達式語言,它支持屬性和方法的直接訪問
簡單屬性表達式:
MVEL代碼
($customer.name=="john")&&(balance>100)
滿足姓名為“john”,且balance必須大于100的customer
支持屬性導航:
Bean屬性導航
MVEL代碼
$customer.address.postalCode="123"等同于$customer.getAddress().setPostalCode("123")
訪問List數據結構
MVEL代碼
$customer.accounts[3]等同于$customer.getAccounts(3)
訪問Map數據結構
MEVL代碼
$customerMap["123"]等同于$customerMap.get["123"]
內置的List、Map和數組arrays
Map:創建一個AccountMap實例-->
MEVL代碼
["001",newAccount("001"),"002",newAccount("002")]
等同于創建了一個Map,并向Map中put了兩個entry。
List:創建一個List實例-->
MEVL代碼
["001","002","003"]
等同于創建了一個List,并向List中add了三個對象。
Arrays:創建一個數組-->
MEVL代碼
{"001","002","003"}
等同于創建了一個Array,并初始化了三個成員。
嵌套
使用這個可以方便的訪問復雜對象中包括的集合類型的對象。
MVEL代碼
listOfPostCode=(postCodein(addressesin$customerS))
這個得到一個postCode列表,它是customers集合中的每一個custemer對象的地址屬性中包含的postCode信息的匯集。
強制轉換
當使用array = {1, 2, 3}時,mvel會自動將元素轉換成integer類型。
返回值
保存變量的值等于最后一次賦予的值。
mvel同時還支持方法調用、控制流、賦值、動態類型等等,使用mvel的性能很好,不過要小心使用。在drools中有一些核心特性就是通過mvel來實現的。
1.9規則的條件部分
And 與
MVEL代碼
$customer: Customer(name=="john",age>20)
在condition中使用換行來表示與
OR 或
MVEL代碼
$customer: Customer(name=="john"||age>20)
Not 非
MVEL代碼
notAccount(type==Account.Type.STUDENT)
表示所有賬戶類型不是STUDENT的賬戶
exists 存在
MVEL代碼
existsAccount(type==Account.Type.STUDENT)
Eval
捕獲異常,只要eval表達式中的結果為true或者false就可以
MVEL代碼
$account:Account()
eval(accountService.isUniqueAccountNumber($account))
返回值約束
MEVL代碼
$customer1:Customer()
Customer(age==($customer.getAge+10))
內置eval
MEVL代碼
$customer1:Customer()
Customer(eval(age==$customer1.getAge()+10))
和上個例子一樣,只是使用了內置的eval來寫的。
內置eval不能使用this,比如:
MEVL代碼
$customer1:Customer()
$customer2:Customer(this!=$customer1)
customer1和customer2不是同一個對象實例
使用內置的eval表達式來描述:
MVEL代碼
$customer1:Customer()
$customer2:Customer(eval($customer2!=$customer1))
注意,在內置的eval中不能使用this來指代自己。
嵌套訪問
MVEL代碼
$customer:Customer()
Account(this==$customer.accounts[0])
得到所有customer對象中的第一個賬號
如果一個嵌套訪問的對象屬性值更改了,我們使用modify來提示drools屬性改變了。
This
this指向當前的Fact
和集合相關的運算
contains
MVEL代碼
$account:Account()
$customer: Customer(accountscontains$account)
$customer:Customer(accountsnotcontains$account)
member of
MVEL代碼
$customer:Customer($accounts:accounts)
Account(thismemberof$accounts)
或
Account(thismemberof$customer.accounts)
From
MVEL代碼
$customer:Customer()
Account()from$customer.accounts
from可以接受service的方法調用后的結果集,也可以指向一個對象或者一個集合
1.10規則的推理部分
規則引擎的作用就是在于根據預先制定的規則去和事實匹配,對符合激發條件的規則,執行規則中定義的推理,作出相應的處理。
有時候,規則和規則之間存在沖突,drools使用沖突解決策略來解決矛盾。有兩種辦法:一個是設置規則的優先級,優先級高的先觸發。另一個是
在推理部分不推薦使用if then這樣的條件判斷語句,它應該是明確的行為,因為條件判斷應該在LHS中就已經明確區分出來了,如果推論部分存在條件判斷的話,應該增加新的規則以滿足要求。這樣做符合最佳實踐。
當一個規則被激活,并且推理部分被執行,它可能會對Fact做一些修改或者更新,這樣的修改和更新可能會激活更多的其他規則,因此,必須在推論部分明確指出這個規則對Fact作出的更新和修改,Drools能夠及時對Fact進行更新,這樣其他規則才能及時應用到最新的Fact數據上來。
推論部分經常使用的幾個函數
modify 修改
更新session中存在的Fact
MVEL代碼
rule"interstcalculation"
no-loop
when
$account:Account()
then
modify($account){
setBalance((double)($account.getBalance()*1.2))
};
end
insert 插入
向session的Fact中新增一個事實
MVEL代碼
insert(newAccount())
retract 收回
從session的Fact中移除一個事實
MEVL代碼
retract(0)
1.11規則的屬性部分
規則屬性出現在rule和when關鍵字之間,用于修改和增強標準的規則行為。
MVEL代碼
rule"ruleattribute"
salience100
dialect"mvel"
no-loop
when
//conditons條件部分
then
//consquence推論部分
end
salience
salience是優先級的意思,它可以為負數,salience越高,表明規則的優先級越高,越先被激發。
默認值是0。
no-loop
表明對于每一個Fact實例,該規則只能被激活一次。
dialect
指定方言。
MVEL代碼
dialect"mvel"
原文地址:http://einverne.github.io/post/2019/03/drools-syntax.html
總結
以上是生活随笔為你收集整理的drools规则语法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机浏览器如何设置才能浏览电脑版网页浏览
- 下一篇: 简单了解学习CSS的伪类(特别是hove