drools 6.4

一. 簡介

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

二. 環(huán)境搭建

1. 從drools官網(wǎng)下載最新drools

http://www.drools.org/download/download.html

Paste_Image.png

2. eclipse的drools插件離線安裝

  • 從官網(wǎng)下載對應(yīng)版本的插件壓縮包
    將下載到的壓縮包解壓,將features,plugins文件夾,拷貝到eclipse的dropins/drools目錄(drools目錄需要自己建立),然后重啟eclipse
Paste_Image.png

3. 使用maven創(chuàng)建drools項目

  • 項目的pom中引入drools的依賴
<dependency>
    <groupId>org.jbpm</groupId>
    <artifactId>jbpm-test</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-api</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-spring</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>knowledge-api</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>6.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-jsr94</artifactId>
    <version>6.4.0.Final</version>
</dependency>

三. 快速入門

  • 使用骨架庫創(chuàng)建一個簡單的java maven項目
  • 創(chuàng)建規(guī)則文件

Sample.drl

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
    <kbase name="dtables" packages="dtables">
        <ksession name="ksession-dtables"/>
    </kbase>
    <kbase name="process" packages="process">
        <ksession name="ksession-process"/>
    </kbase>
</kmodule>
  • 定義規(guī)則之間的關(guān)系

kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>
  • 編寫測試類
package com.sample;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class DroolsTest {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            KieSession kSession = kContainer.newKieSession("ksession-rules");

            // go !
            Message message = new Message();
            message.setMessage("Hello World");
            message.setStatus(Message.HELLO);
            kSession.insert(message);
            kSession.fireAllRules();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public static class Message {

        public static final int HELLO = 0;
        public static final int GOODBYE = 1;

        private String message;

        private int status;

        public String getMessage() {
            return this.message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public int getStatus() {
            return this.status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

    }

}

四. 項目結(jié)構(gòu)說明

Paste_Image.png

五. drools工作流程

六. 規(guī)則文件(.drl文件)

規(guī)則語法:

package /*包名,必須,且必須在第一行,不必與規(guī)則為文件的物理路徑一致舔示,若自定義函數(shù)或查詢屬于同一包名碟婆,不管物理位置如何,都可以調(diào)用*/

import /*需要導(dǎo)入的類名*/

global /*全局變量*/

function /*函數(shù)*/

query /*查詢*/

rule /*規(guī)則,可以有多個*/

規(guī)則文件

package com.qc.drools;

import com.qc.model.Student;

global java.util.List.studentList;

function void sysName(){
  System.out.println("我是張三");
}

rule "規(guī)則名稱"
    <屬性><值>
    when
        條件 Left Hand Side
    then
        結(jié)果 Right Hand Side

package:對一個規(guī)則文件而言,package是必須定義的斩郎,必須放在規(guī)則文件第一行脑融。特別的是,package的名字是隨意的缩宜,不必必須對應(yīng)物理路徑肘迎,跟java的package的概念不同甥温,這里只是邏輯上的一種區(qū)分

import:導(dǎo)入規(guī)則文件需要使用到的外部變量,這里的使用方法跟java相同妓布,但是不同于java的是姻蚓,這里的import導(dǎo)入的不僅僅可以是一個類,也可以是這個類中的某一個可訪問的靜態(tài)方法
比如:
import com.drools.demo.point.PointDomain;
import com.drools.demo.point.PointDomain.getById;

global: 定義global全局變量匣沼,通常用于返回數(shù)據(jù)和提供服務(wù)全局變量與fact不一樣狰挡,引擎不能知道全局變量的改變必須要在插入fact之前,設(shè)置global變量

function: 規(guī)則中的代碼塊释涛,封裝業(yè)務(wù)操作加叁,提高代碼復(fù)用函數(shù)以function開頭,其它與JAVA方法類似業(yè)務(wù)代碼書寫采用的是標(biāo)準(zhǔn)JAVA語法

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

屬性: activation-group喝噪、agenda-group础嫡、auto-focus、date-effective仙逻、date-expires驰吓、dialect、duration系奉、duration-value檬贰、enabled、lock-on-active缺亮、no-loop翁涤、ruleflow-group、salience

salience: 它的作用是用來設(shè)置規(guī)則執(zhí)行的優(yōu)先級萌踱,salience 屬性的值是一個數(shù)字葵礼,數(shù)字越大執(zhí)行優(yōu)先級越高,同時它的值可以是一個負(fù)數(shù)并鸵。默認(rèn)情況下鸳粉,規(guī)則的salience 默認(rèn)值為0,所以如果我們不手動設(shè)置規(guī)則的salience 屬性园担,那么它的執(zhí)行順序是隨機的
int型届谈,默認(rèn)值為0

no-loop: 在DRL的then子句中枯夜,如果出現(xiàn)insert、update艰山、modify湖雹、retract等方法對實例(Fact)做出修改時,當(dāng)前規(guī)則執(zhí)行完成后會觸發(fā)該規(guī)則使其再執(zhí)行一次曙搬;將no-loop設(shè)置為true則會強制規(guī)則在出現(xiàn)上述方法的情況下也只執(zhí)行一次boolean型摔吏,默認(rèn)值為false

date-effective: 該屬性是用來控制規(guī)則只有在到達(dá)后才會觸發(fā),在規(guī)則運行時纵装,引擎會自動拿當(dāng)前操作系統(tǒng)的時候與date-effective 設(shè)置的時間值進(jìn)行比對征讲,只有當(dāng)系統(tǒng)時間>=date-effective 設(shè)置的時間值時,規(guī)則才會觸發(fā)執(zhí)行搂擦,否則執(zhí)行將不執(zhí)行稳诚。在沒有設(shè)置該屬性的情況下,規(guī)則隨時可以觸發(fā)瀑踢,沒有這種限制。 date-effective 的值為一個日期型的字符串才避,默認(rèn)情況下橱夭,date-effective 可接受的日期格式為“dd-MMM-yyyy”,例如2009 年9 月25 日在設(shè)置為date-effective 的值時桑逝,如果您的操作系統(tǒng)為英文的棘劣,那么應(yīng)該寫成“25-Sep-2009”;如果是英文操作系統(tǒng)“25-九月-2009”
當(dāng)前規(guī)則的生效時間string型楞遏,無默認(rèn)值茬暇;值中需包含日期和時間

date-expires: 該屬性的作用與date-effective 屬性恰恰相反, date-expires 的作用是用來設(shè)置規(guī)則的有效期寡喝,引擎在執(zhí)行規(guī)則的時候糙俗,會檢查規(guī)則有沒有date-expires 屬性,如果有的話预鬓,那么會將這個屬性的值與當(dāng)前系統(tǒng)時間進(jìn)行比對巧骚,如果大于系統(tǒng)時間,那么規(guī)則就執(zhí)行格二,否則就不執(zhí)行劈彪。該屬性的值同樣也是一個日期類型,默認(rèn)格式也是“dd-MMM-yyyy”顶猜,具體用法與date-effective 屬性相同
當(dāng)前規(guī)則的失效時間string型沧奴,無默認(rèn)值;值中需包含日期和時間

enabled: 它是用來定義一個規(guī)則是否可用的长窄。該屬性的值是一個布爾值滔吠,默認(rèn)該屬性的值為true纲菌,表示規(guī)則是可用的,如果手工為一個規(guī)則添加一個enabled 屬性屠凶,并且設(shè)置其enabled 屬性值為false驰后,那么引擎就不會執(zhí)行該規(guī)則

dialect: 該屬性用來定義規(guī)則當(dāng)中要使用的語言類型,目前Drools5 版本當(dāng)中支持兩種類型的語言:mvel 和java矗愧,默認(rèn)情況下灶芝,如果沒有手工設(shè)置規(guī)則的dialect,那么使用的java 語言
設(shè)置規(guī)則所使用的語言
string型唉韭,默認(rèn)值根據(jù)package值判斷夜涕,值域為java或mvel

duration: 對于一個規(guī)則來說,如果設(shè)置了該屬性属愤,那么規(guī)則將在該屬性指定的值之后在另外一個線程里觸發(fā)女器。該屬性對應(yīng)的值為一個長整型,單位是毫秒住诸,代碼清單2-37 里的規(guī)則rule1 添加了duration 屬性驾胆,它的值為3000,表示該規(guī)則將在3000 毫秒之后在另外一個線程里觸發(fā)
設(shè)置DRL文件開始執(zhí)行之后延遲多長時間開始執(zhí)行這條規(guī)則
long型贱呐,無默認(rèn)值

lock-on-active: 當(dāng)在規(guī)則上使用ruleflow-group 屬性或agenda-group 屬性的時候丧诺,將lock-on-action 屬性的值設(shè)置為true,可能避免因某些Fact 對象被修改而使已經(jīng)執(zhí)行過的規(guī)則再次被激活執(zhí)行奄薇〔笛郑可以看出該屬性與no-loop 屬性有相似之處,no-loop 屬性是為了避免Fact 修改或調(diào)用了insert馁蒂、retract呵晚、update 之類而導(dǎo)致規(guī)則再次激活執(zhí)行,這里的lock-on-action 屬性也是起這個作用沫屡,lock-on-active 是no-loop 的增強版屬性饵隙,它主要作用在使用ruleflow-group 屬性或agenda-group 屬性的時候。lock-on-active 屬性默認(rèn)值為false
boolean型谁鳍,默認(rèn)值為false

activation-group: 該屬性的作用是將若干個規(guī)則劃分成一個組癞季,用一個字符串來給這個組命名,這樣在執(zhí)行的時候倘潜,具有相同activation-group 屬性的規(guī)則中只要有一個會被執(zhí)行绷柒,其它的規(guī)則都將不再執(zhí)行。也就是說涮因,在一組具有相同activation-group 屬性的規(guī)則當(dāng)中废睦,只有一個規(guī)則會被執(zhí)行,其它規(guī)則都將不會被執(zhí)行养泡。當(dāng)然對于具有相同activation-group 屬性的規(guī)則當(dāng)中究竟哪一個會先執(zhí)行嗜湃,則可以用類似salience 之類屬性來實現(xiàn)
不基于任何條件將規(guī)則分組string型奈应,無默認(rèn)值

agenda-group: 規(guī)則的調(diào)用與執(zhí)行是通過StatelessSession 或StatefulSession 來實現(xiàn)的,一般的順序是創(chuàng)建一個StatelessSession 或StatefulSession购披,將各種經(jīng)過編譯的規(guī)則的package 添加到session當(dāng)中杖挣,接下來將規(guī)則當(dāng)中可能用到的Global 對象和Fact 對象插入到Session 當(dāng)中,最后調(diào)用fireAllRules 方法來觸發(fā)刚陡、執(zhí)行規(guī)則惩妇。在沒有調(diào)用最后一步fireAllRules 方法之前,所有的規(guī)則及插入的Fact 對象都存放在一個名叫Agenda 表的對象當(dāng)中筐乳,這個Agenda 表中每一個規(guī)則及與其匹配相關(guān)業(yè)務(wù)數(shù)據(jù)叫做Activation歌殃,在調(diào)用fireAllRules 方法后,這些Activation 會依次執(zhí)行蝙云,這些位于Agenda 表中的Activation 的執(zhí)行順序在沒有設(shè)置相關(guān)用來控制順序的屬性時(比如salience 屬性)氓皱,它的執(zhí)行順序是隨機的,不確定的勃刨。 Agenda Group 是用來在Agenda 的基礎(chǔ)之上波材,對現(xiàn)在的規(guī)則進(jìn)行再次分組,具體的分組方法可以采用為規(guī)則添加agenda-group 屬性來實現(xiàn)身隐。agenda-group 屬性的值也是一個字符串各聘,通過這個字符串,可以將規(guī)則分為若干個Agenda Group抡医,默認(rèn)情況下,引擎在調(diào)用這些設(shè)置了agenda-group 屬性的規(guī)則的時候需要顯示的指定某個Agenda Group 得到Focus(焦點)早敬,這樣位于該Agenda Group 當(dāng)中的規(guī)則才會觸發(fā)執(zhí)行忌傻,否則將不執(zhí)行
基于Agenda將規(guī)則分組;只有當(dāng)某個Agenda組獲取到焦點(focus)時搞监,該組的規(guī)則才會被執(zhí)行string型水孩,默認(rèn)值為MAIN

auto-focus: 前面我們也提到auto-focus 屬性,它的作用是用來在已設(shè)置了agenda-group 的規(guī)則上設(shè)置該規(guī)則是否可以自動獨取Focus琐驴,如果該屬性設(shè)置為true俘种,那么在引擎執(zhí)行時,就不需要顯示的為某個Agenda Group 設(shè)置Focus绝淡,否則需要宙刘。對于規(guī)則的執(zhí)行的控制,還可以使用Agenda Filter 來實現(xiàn)牢酵。在Drools 當(dāng)中悬包,提供了一個名為org.drools.runtime.rule.AgendaFilter 的Agenda Filter 接口,用戶可以實現(xiàn)該接口馍乙,通過規(guī)則當(dāng)中的某些屬性來控制規(guī)則要不要執(zhí)行布近。org.drools.runtime.rule.AgendaFilter 接口只有一個方法需要實現(xiàn)垫释,方法體如下: public boolean accept(Activation activation); 在該方法當(dāng)中提供了一個Activation 參數(shù),通過該參數(shù)我們可以得到當(dāng)前正在執(zhí)行的規(guī)則對象或其它一些屬性撑瞧,該方法要返回一個布爾值棵譬,該布爾值就決定了要不要執(zhí)行當(dāng)前這個規(guī)則,返回true 就執(zhí)行規(guī)則预伺,否則就不執(zhí)行
與agenda-group配合使用订咸,設(shè)置焦點的是否可以自動獲取boolean型,默認(rèn)值為false

ruleflow-group: 基于ruleflow將規(guī)則分組string型扭屁,無默認(rèn)值算谈,作用是用來將規(guī)則劃分為一個個的組,然后在規(guī)則流當(dāng)中通過使用ruleflow-group 屬性的值料滥,從而使用對應(yīng)的規(guī)則

Left Hand Side: Conditions / LHS —匹配模式(Patterns)
沒有字段約束的Pattern
Person()

有文本字段約束的Pattern
Person( name == “bob” )

字段綁定的Pattern
Person( $name : name == “bob” )
變量名稱可以是任何合法的java變量然眼,$是可選的,可用于區(qū)分字段和變量

Fact綁定的Pattern
$bob : Person( name == “bob” )

字段綁定的Pattern

變量約束的Pattern
Person( name == $name )

比較操作符: > >= < <= == != contains / not contains / memberOf / not memberOf /matches/ not matches

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

not memberOf: 與memberOf的作用相反

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

not matches: 正好相反

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

update: 更新workingMemory中的Fact對象

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

retract: 刪除

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市烤惊,隨后出現(xiàn)的幾起案子乔煞,更是在濱河造成了極大的恐慌,老刑警劉巖柒室,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渡贾,死亡現(xiàn)場離奇詭異,居然都是意外死亡雄右,警方通過查閱死者的電腦和手機空骚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擂仍,“玉大人囤屹,你說我怎么就攤上這事》揽” “怎么了牺丙?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我冲簿,道長粟判,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任峦剔,我火速辦了婚禮档礁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吝沫。我一直安慰自己呻澜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布惨险。 她就那樣靜靜地躺著羹幸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辫愉。 梳的紋絲不亂的頭發(fā)上栅受,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機與錄音恭朗,去河邊找鬼屏镊。 笑死,一個胖子當(dāng)著我的面吹牛痰腮,可吹牛的內(nèi)容都是我干的而芥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼膀值,長吁一口氣:“原來是場噩夢啊……” “哼棍丐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沧踏,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤骄酗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悦冀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體下愈,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡律想,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年课竣,在試婚紗的時候發(fā)現(xiàn)自己被綠了椅文。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泪酱。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡屁擅,死狀恐怖序宦,靈堂內(nèi)的尸體忽然破棺而出滥玷,到底是詐尸還是另有隱情辟癌,我是刑警寧澤寒屯,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響寡夹,放射性物質(zhì)發(fā)生泄漏处面。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一菩掏、第九天 我趴在偏房一處隱蔽的房頂上張望魂角。 院中可真熱鬧,春花似錦智绸、人聲如沸野揪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斯稳。三九已至,卻和暖如春迹恐,著一層夾襖步出監(jiān)牢的瞬間挣惰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工系草, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留通熄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓找都,卻偏偏與公主長得像唇辨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子能耻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 概述(Overview) 以.drl為擴展名的文件赏枚,是Drools中的規(guī)則文件,規(guī)則文件的編寫晓猛,遵循Drools規(guī)...
    老羊_肖恩閱讀 41,767評論 4 31
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理饿幅,服務(wù)發(fā)現(xiàn),斷路器戒职,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Drools規(guī)則文件——語法屬性 salience 功能:設(shè)置規(guī)制執(zhí)行的優(yōu)先級值:數(shù)字(數(shù)字越大執(zhí)行優(yōu)先級越高)...
    天堂的碼頭閱讀 3,164評論 0 2
  • 關(guān)于親子閱讀的20句話 1.你孩子現(xiàn)在開始閱讀并不晚栗恩。當(dāng)然,多早都不會太早洪燥,胎兒也是人磕秤。 2.三歲以前最好不要指讀...
    Sybil麻麻閱讀 638評論 0 0
  • ■3月份的時候,一個朋友認(rèn)識了一個很喜歡很向上的男孩子捧韵,她為此和男朋友分手并說明了理由市咆,然后和喜歡的男孩子告白,雖...
    N一米八閱讀 267評論 0 0