天天看點

drools規則文法

1、基本的比對規則

1.1變量

drools使用比對的方式對Fact進行比對,

比如

MVEL代碼  

drools規則文法

  1. account : Account(balance > 100)  

 這個規則的含義就是在Fact中找到類型為Account,且balance屬性值大于100的所有Account執行個體。

可以指定變量來描述一個類型或者一個映射一個類的屬性,

drools規則文法
  1. $account : Account($type : type)  

 使用$Variable來定義一個變量,這裡定義了兩個變量,$account表示定義一個類型為Account的變量,而$type映射Account類型中的type屬性。定義變量是為了在後續的規則中使用。

drools規則文法
  1. $account : Account(balance >100)   
  2. Customer(account == $account)  

 這個就是說要找到一些Custom類型的Fact,且其account屬性必須滿足前面定義的balance>100的條件。

1.2類型

drools支援各種java資料類型

String:字元串

drools規則文法
  1. Customer(name == "john")  

正規表達式:

drools規則文法
  1. Customer(name matches "[A-Z][a-z]+")  

表示Customer類型的name屬性必須滿足首字母為大寫A-Z,且第二位以後有一個或者多個小寫的a-z組成。

Date:日期類型

drools規則文法
  1. Account(dateCreate > "01-Feb-2009")  

日期的格式預設是"dd-mmmm-yyyy",可以更改。

Boolean:布爾類型

drools規則文法
  1. Transaction(isApprove == true)  

Enum:枚舉類型

drools規則文法
  1. Account(type == Account.Type.STUDENT)  

1.3注釋

單行注釋://或者#

多行注釋: /*   */

1.4包

drools規則文法
  1. package com.kingsun.drools.rules  

聲明該規則檔案所屬的包,是一種namespace組織方式,和java的包類似,實體上不需要存在相應的目錄結構,它隻是邏輯上的劃分。

1.5導入

import可以導入在規則中使用到的類,也可以導入在規則中使用到的外部定義的functiong

drools規則文法
  1. import java.util.Map;  
  2. import com.kingsun.drools.service.LegacyBankService.extractData;  

當導入方法時,這個方法必須是static的,因為利用的是jdk1.5的static import特性。

1.6全局變量global

聲明一個global變量

drools規則文法
  1. global ReportFactory reportFactory;  

給全局變量指派

drools規則文法
  1. session.setGlobal("reportFactory", reportFactory);  

或者

drools規則文法
  1. List<Command> commands = new ArrayList<Command>();  
  2. commmands.add(CommandFactory.newSetGlobal("reportFactory", reportFactory));  

 使用全局變量

drools規則文法
  1. session.getGlobals();  

1.7函數Functions

function可以在規則檔案中定義,但更多的是使用外部類中定義的static方法,這樣隻要java中可以實作的邏輯,在規則中都可以做為function調用。

調用外部類的functiong需要注意的是方法必須是靜态的,static,而且這個類可以在Help輔助類中定義。

外部類需要import,此時在function中用到的參數類型也需要import。

如: 在外部的ValidationHelper輔助類中定一個一個static方法

Java代碼  

drools規則文法
  1. public static double calculateAccount(Account account) {  
  2.     return 100 + account.balance * 1.2;  
  3. }  

在規則drl檔案中可以這麼使用:

Drl代碼  

drools規則文法
  1. import com.kingsun.drools.domain.Account;  
  2. import function com.kingsun.drools.util.ValidationHelper.calculateAccount;  
  3. rule "validation account"  
  4.     when  
  5.         $account : Account(balance > 100)  
  6.     then  
  7.         Account(balance == calculateAccount($account));  
  8. end  

1.8方言dialect

在規則表達式中可以使用方言來簡化表達式,使之更加具有可讀性。

drools規則文法
  1. package com.kingsun.drools.rules;  
  2. dialect "mvel"  

方言預設的是java,drools也支援mvel,在package的後面聲明該規則檔案使用的方言

 mvel

   mvel是一種基于java應用程式的表達式語言,它支援屬性和方法的直接通路

    簡單屬性表達式:

drools規則文法
  1. ($customer.name == "john") && (balance > 100)   

    滿足姓名為“john”,且balance必須大于100的customer

         支援屬性導航:

               Bean屬性導航

drools規則文法
  1. $customer.address.postalCode = "123" 等同于 $customer.getAddress().setPostalCode("123")  

              通路List資料結構

drools規則文法
  1. $customer.accounts[3] 等同于 $customer.getAccounts(3)  

              通路Map資料結構

MEVL代碼  

drools規則文法
  1. $customerMap["123"] 等同于$customerMap.get["123"]  

        内置的List、Map和數組arrays

               Map:建立一個AccountMap執行個體-->

drools規則文法
  1. ["001", new Account("001"), "002", new Account("002")]  

 等同于建立了一個Map,并向Map中put了兩個entry。

               List:建立一個List執行個體-->

drools規則文法
  1. ["001", "002", "003"]   

 等同于建立了一個List,并向List中add了三個對象。

              Arrays:建立一個數組-->

drools規則文法
  1. {"001", "002", "003"}  

          等同于建立了一個Array,并初始化了三個成員。

      嵌套

       使用這個可以友善的通路複雜對象中包括的集合類型的對象。

drools規則文法
  1. listOfPostCode = (postCode in (addresses in $customerS))  

     這個得到一個postCode清單,它是customers集合中的每一個custemer對象的位址屬性中包含的postCode資訊的彙集。

      強制轉換

      當使用array = {1, 2, 3}時,mvel會自動将元素轉換成integer類型。

      傳回值

      儲存變量的值等于最後一次賦予的值。

      mvel同時還支援方法調用、控制流、指派、動态類型等等,使用mvel的性能很好,不過要小心使用。在drools中有一些核心特性就是通過mvel來實作的。

1.9規則的條件部分

 And 與

drools規則文法
  1. $customer : Customer(name == "john", age > 20)  

在condition中使用換行來表示與

OR 或

drools規則文法
  1. $customer : Customer(name == "john" || age > 20)  

 Not 非

drools規則文法
  1. not Account(type == Account.Type.STUDENT)   

表示所有賬戶類型不是STUDENT的賬戶

exists 存在

drools規則文法
  1. exists Account(type == Account.Type.STUDENT)  

Eval

捕獲異常,隻要eval表達式中的結果為true或者false就可以

drools規則文法
  1. $account : Account()  
  2. eval(accountService.isUniqueAccountNumber($account))  

傳回值限制

drools規則文法
  1. $customer1 : Customer()  
  2. Customer(age == ($customer.getAge + 10))  

内置eval

drools規則文法
  1. Customer(eval(age == $customer1.getAge() + 10))  

和上個例子一樣,隻是使用了内置的eval來寫的。

内置eval不能使用this,比如:

drools規則文法
  1. $customer2 : Customer(this != $customer1)  

customer1和customer2不是同一個對象執行個體

使用内置的eval表達式來描述:

drools規則文法
  1. $customer2 : Customer(eval($customer2 != $customer1))  

注意,在内置的eval中不能使用this來指代自己。

嵌套通路

drools規則文法
  1. $customer : Customer()  
  2. Account(this == $customer.accounts[0])  

得到所有customer對象中的第一個賬号

如果一個嵌套通路的對象屬性值更改了,我們使用modify來提示drools屬性改變了。

This

this指向目前的Fact

和集合相關的運算

contains

drools規則文法
  1. $customer : Customer(accounts contains $account)  
  2. $customer : Customer(accounts not contains $account)  

member of

drools規則文法
  1. $customer : Customer($accounts : accounts)  
  2. Account(this member of $accounts)  
  3. 或  
  4. Account(this member of $customer.accounts)  

From

drools規則文法
  1. Account() from $customer.accounts  

from可以接受service的方法調用後的結果集,也可以指向一個對象或者一個集合

1.10規則的推理部分

規則引擎的作用就是在于根據預先制定的規則去和事實比對,對符合激發條件的規則,執行規則中定義的推理,作出相應的處理。

有時候,規則和規則之間存在沖突,drools使用沖突解決政策來解決沖突。有兩種辦法:一個是設定規則的優先級,優先級高的先觸發。另一個是

在推理部分不推薦使用if then這樣的條件判斷語句,它應該是明确的行為,因為條件判斷應該在LHS中就已經明确區分出來了,如果推論部分存在條件判斷的話,應該增加新的規則以滿足要求。這樣做符合最佳實踐。

當一個規則被激活,并且推理部分被執行,它可能會對Fact做一些修改或者更新,這樣的修改和更新可能會激活更多的其他規則,是以,必須在推論部分明确指出這個規則對Fact作出的更新和修改,Drools能夠及時對Fact進行更新,這樣其他規則才能及時應用到最新的Fact資料上來。

推論部分經常使用的幾個函數

modify 修改

更新session中存在的Fact

drools規則文法
  1. rule "interst calculation"  
  2. no-loop  
  3.     when   
  4.         $account : Account()  
  5.         modify($account) {  
  6.             setBalance((double)($account.getBalance() * 1.2))  
  7.         };  

insert 插入

向session的Fact中新增一個事實

drools規則文法
  1. insert(new Account())  

retract 收回

從session的Fact中移除一個事實

drools規則文法
  1. retract(0)  

1.11規則的屬性部分

規則屬性出現在rule和when關鍵字之間,用于修改和增強标準的規則行為。

drools規則文法
  1. rule "rule attribute"  
  2. salience 100  
  3.     when       
  4.         //conditons條件部分  
  5.         //consquence推論部分  

salience

salience是優先級的意思,它可以為負數,salience越高,表明規則的優先級越高,越先被激發。

預設值是0。

no-loop

表明對于每一個Fact執行個體,該規則隻能被激活一次。

dialect

指定方言。

drools規則文法

原文位址:http://einverne.github.io/post/2019/03/drools-syntax.html

繼續閱讀