国产99福利精品视频|杨幂精品国产福利在线|国精品午夜福利视频不卡|欧美精品黄网站在线播放|精品国产乱码久久久久久久|国产大片中文字幕在线观看|国产肥熟女视频一区二区三区|国产乱码无码视频一区二区三区

JAVA規(guī)則引擎 -- Drools

來源:長沙北大青鳥大計校區(qū)|發(fā)布時間:2015-07-21 14:32:30

 

Drools是一個基于java的規(guī)則引擎,開源的,可以將復(fù)雜多變的規(guī)則從硬編碼中解放出來,以規(guī)則腳本的形式存放在文件中,使得規(guī)則的變更不需要修正代碼重啟機器就可以立即在線上環(huán)境生效。


1、Drools語法

 

開始語法之前首先要了解一下drools的基本工作過程,通常而言我們使用一個接口來做事情,首先要穿進去參數(shù),其次要獲取到接口的實現(xiàn)執(zhí)行完畢后的結(jié)果,而drools也是一樣的,我們需要傳遞進去數(shù)據(jù),用于規(guī)則的檢查,調(diào)用外部接口,同時還可能需要獲取到規(guī)則執(zhí)行完畢后得到的結(jié)果。在drools中,這個傳遞數(shù)據(jù)進去的對象,術(shù)語叫 Fact對象。Fact對象是一個普通的java bean,規(guī)則中可以對當(dāng)前的對象進行任何的讀寫操作,調(diào)用該對象提供的方法,當(dāng)一個java bean插入到workingMemory中,規(guī)則使用的是原有對象的引用,規(guī)則通過對fact對象的讀寫,實現(xiàn)對應(yīng)用數(shù)據(jù)的讀寫,對于其中的屬性,需要提供getter setter訪問器,規(guī)則中,可以動態(tài)的往當(dāng)前workingMemory中插入刪除新的fact對象。

 

規(guī)則文件可以使用 .drl文件,也可以是xml文件,這里我們使用drl文件。

 

規(guī)則語法:

 

package:對一個規(guī)則文件而言,package是必須定義的,必須放在規(guī)則文件第一行。特別的是,package的名字是隨意的,不必必須對應(yīng)物理路徑,跟java的package的概念不同,這里只是邏輯上的一種區(qū)分。同樣的package下定義的function和query等可以直接使用。

 

比如:package com.drools.demo.point

 

import:導(dǎo)入規(guī)則文件需要使用到的外部變量,這里的使用方法跟java相同,但是不同于java的是,這里的import導(dǎo)入的不僅僅可以是一個類,也可以是這個類中的某一個可訪問的靜態(tài)方法。

 

比如:

 

import com.drools.demo.point.PointDomain;

 

import com.drools.demo.point.PointDomain.getById;

 

rule:定義一個規(guī)則。rule "ruleName"。一個規(guī)則可以包含三個部分:

 

屬性部分:定義當(dāng)前規(guī)則執(zhí)行的一些屬性等,比如是否可被重復(fù)執(zhí)行、過期時間、生效時間等。

 

條件部分,即LHS,定義當(dāng)前規(guī)則的條件,如  when Message(); 判斷當(dāng)前workingMemory中是否存在Message對象。

 

結(jié)果部分,即RHS,這里可以寫普通java代碼,即當(dāng)前規(guī)則條件滿足后執(zhí)行的操作,可以直接調(diào)用Fact對象的方法來操作應(yīng)用。

 

規(guī)則事例:

 

rule "name"

 

       no-loop true

 

       when

 

               $message:Message(status == 0)

 

       then

 

               System.out.println("fit");

 

               $message.setStatus(1);

 

               update($message);

 

end

 

上述的屬性中:

 

no-loop : 定義當(dāng)前的規(guī)則是否不允許多次循環(huán)執(zhí)行,默認(rèn)是false,也就是當(dāng)前的規(guī)則只要滿足條件,可以無限次執(zhí)行。什么情況下會出現(xiàn)一條規(guī)則執(zhí)行過一次又被多次重復(fù)執(zhí)行呢?drools提供了一些api,可以對當(dāng)前傳入workingMemory中的Fact對象進行修改或者個數(shù)的增減,比如上述的update方法,就是將當(dāng)前的workingMemory中的Message類型的Fact對象進行屬性更新,這種操作會觸發(fā)規(guī)則的重新匹配執(zhí)行,可以理解為Fact對象更新了,所以規(guī)則需要重新匹配一遍,那么疑問是之前規(guī)則執(zhí)行過并且修改過的那些Fact對象的屬性的數(shù)據(jù)會不會被重置?結(jié)果是不會,已經(jīng)修改過了就不會被重置,update之后,之前的修改都會生效。當(dāng)然對Fact對象數(shù)據(jù)的修改并不是一定需要調(diào)用update才可以生效,簡單的使用set方法設(shè)置就可以完成,這里類似于java的引用調(diào)用,所以何時使用update是一個需要仔細(xì)考慮的問題,一旦不慎,極有可能會造成規(guī)則的死循環(huán)。上述的no-loop true,即設(shè)置當(dāng)前的規(guī)則,只執(zhí)行一次,如果本身的RHS部分有update等觸發(fā)規(guī)則重新執(zhí)行的操作,也不要再次執(zhí)行當(dāng)前規(guī)則。

 

但是其他的規(guī)則會被重新執(zhí)行,豈不是也會有可能造成多次重復(fù)執(zhí)行,數(shù)據(jù)紊亂甚至死循環(huán)?答案是使用其他的標(biāo)簽限制,也是可以控制的:lock-on-active true

 

lock-on-active true:通過這個標(biāo)簽,可以控制當(dāng)前的規(guī)則只會被執(zhí)行一次,因為一個規(guī)則的重復(fù)執(zhí)行不一定是本身觸發(fā)的,也可能是其他規(guī)則觸發(fā)的,所以這個是no-loop的加強版。當(dāng)然該標(biāo)簽正規(guī)的用法會有其他的標(biāo)簽的配合,后續(xù)提及。

 

date-expires:設(shè)置規(guī)則的過期時間,默認(rèn)的時間格式:“日-月-年”,中英文格式相同,但是寫法要用各自對應(yīng)的語言,比如中文:"29-七月-2010",但是還是推薦使用更為精確和習(xí)慣的格式,這需要手動在java代碼中設(shè)置當(dāng)前系統(tǒng)的時間格式,后續(xù)提及。屬性用法舉例:date-expires "2011-01-31 23:59:59" // 這里我們使用了更為習(xí)慣的時間格式

 

date-effective:設(shè)置規(guī)則的生效時間,時間格式同上。

 

duration:規(guī)則定時,duration 3000   3秒后執(zhí)行規(guī)則

 

salience:優(yōu)先級,數(shù)值越大越先執(zhí)行,這個可以控制規(guī)則的執(zhí)行順序。

 

 

其他的屬性可以參照相關(guān)的api文檔查看具體用法,此處略。

 

 

 

規(guī)則的條件部分,即LHS部分:

 

when:規(guī)則條件開始。條件可以單個,也可以多個,多個條件一次排列,比如

 

when

 

         eval(true)

 

         $customer:Customer()

 

         $message:Message(status==0)

 

上述羅列了三個條件,當(dāng)前規(guī)則只有在這三個條件都匹配的時候才會執(zhí)行RHS部分,三個條件中第一個

 

eval(true):是一個默認(rèn)的api,true 無條件執(zhí)行,類似于 while(true)

 

$message:Message(status==0) 這句話標(biāo)示的:當(dāng)前的workingMemory存在Message類型并且status屬性的值為0的Fact對象,這個對象通常是通過外部java代碼插入或者自己在前面已經(jīng)執(zhí)行的規(guī)則的RHS部分中insert進去的。

 

前面的$message代表著當(dāng)前條件的引用變量,在后續(xù)的條件部分和RHS部分中,可以使用當(dāng)前的變量去引用符合條件的FACT對象,修改屬性或者調(diào)用方法等?蛇x,如果不需要使用,則可以不寫。

 

條件可以有組合,比如:

 

Message(status==0 || (status > 1 && status <=100))

 

RHS中對Fact對象private屬性的操作必須使用getter和setter方法,而RHS中則必須要直接用.的方法去使用,比如

 

  $order:Order(name=="qu")
  $message:Message(status==0 && orders contains $order && $order.name=="qu")

 

特別的是,如果條件全部是 &&關(guān)系,可以使用“,”來替代,但是兩者不能混用

 

如果現(xiàn)在Fact對象中有一個List,需要判斷條件,如何判斷呢?

 

看一個例子:

 

Message {

 

        int status;

 

        List<String> names;

 

}

 

$message:Message(status==0 && names contains "網(wǎng)易" && names.size >= 1)

 

上述的條件中,status必須是0,并且names列表中含有“網(wǎng)易”并且列表長度大于等于1

 

contains:對比是否包含操作,操作的被包含目標(biāo)可以是一個復(fù)雜對象也可以是一個簡單的值。

 

Drools提供了十二中類型比較操作符:

 

>  >=  <  <=  ==  !=  contains / not contains / memberOf / not memberOf /matches/ not matches

 

not contains:與contains相反。

 

memberOf:判斷某個Fact屬性值是否在某個集合中,與contains不同的是他被比較的對象是一個集合,而contains被比較的對象是單個值或者對象。

 

not memberOf:正好相反。

 

matches:正則表達(dá)式匹配,與java不同的是,不用考慮'/'的轉(zhuǎn)義問題

 

 

not matches:正好相反。

 

 

 

規(guī)則的結(jié)果部分

 

當(dāng)規(guī)則條件滿足,則進入規(guī)則結(jié)果部分執(zhí)行,結(jié)果部分可以是純java代碼,比如:

 

then

 

       System.out.println("OK"); //會在控制臺打印出ok

 

end

 

當(dāng)然也可以調(diào)用Fact的方法,比如  $message.execute();操作數(shù)據(jù)庫等等一切操作。

 

結(jié)果部分也有drools提供的方法:

 

insert:往當(dāng)前workingMemory中插入一個新的Fact對象,會觸發(fā)規(guī)則的再次執(zhí)行,除非使用no-loop限定;

 

update:更新

 

modify:修改,與update語法不同,結(jié)果都是更新操作

 

retract:刪除

 

RHS部分除了調(diào)用Drools提供的api和Fact對象的方法,也可以調(diào)用規(guī)則文件中定義的方法,方法的定義使用 function 關(guān)鍵字

 

function void console {

 

   System.out.println();

 

   StringUtils.getId();// 調(diào)用外部靜態(tài)方法,StringUtils必須使用import導(dǎo)入,getId()必須是靜態(tài)方法

 

}

 

Drools還有一個可以定義類的關(guān)鍵字:

 

declare 可以再規(guī)則文件中定義一個class,使用起來跟普通java對象相似,你可以在RHS部分中new一個并且使用getter和setter方法去操作其屬性。

 

declare Address
@author(quzishen) // 元數(shù)據(jù),僅用于描述信息

 

@createTime(2011-1-24)
city : String @maxLengh(100)
postno : int
end

 

上述的'@'是什么呢?是元數(shù)據(jù)定義,用于描述數(shù)據(jù)的數(shù)據(jù)~,沒什么執(zhí)行含義

你可以在RHS部分中使用Address address = new Address()的方法來定義一個對象

上一篇:java數(shù)據(jù)庫操作
下一篇:還在遲疑是否選擇學(xué)習(xí)Java?看看這六大優(yōu)勢

熱門話題

招生熱線: 4008-0731-86 / 0731-82186801

學(xué)校地址: 長沙市天心區(qū)團結(jié)路6號

Copyright © 2006 | 湖南大計信息科技有限公司 版權(quán)所有

湘ICP備14017520號-3

關(guān)注我們
在線咨詢
嘿,我來幫您!