kie(Knowledge Is Everything)
package rules.rulesHello //規則邏輯路徑
rule "test001" //rule 規則開始 "test001" 規則名
when
eval(true); //規則條件
then
System.out.println("hello world"); //規則返回結果
end //規則結束
規則文件內容包含三大塊 :包路徑,引用,規則體(核心)
規則體:分為 LHS,RHS兩大功能模塊
1.LHS(Left Hand Side):條件部分,when與then中間部分
2.RHS(Right Hand Side):結果部分,then與end中間部分
Drools規則引擎中傳遞的數據,術語稱Fact對象,Fact對象是一個普通的javaBean,規則體可以對當前對象進行任何的讀寫操作。Fact插入Working Memory(內存儲存)
(1)一個kmodule.xml配置可以包含多個kbase
(2)kbase的packages屬性,值為src/main/resources目錄下文件夾名稱,可以同時定義多個包,以逗號進行分隔。可以包含多個ksession
(3)每個ksession,名稱可以是任意字符,不能重復
(4)packages指定的所有規則文件都會讀取,子目錄中規則文件不會被加載
二、基礎語法
規則文件關鍵字:
關鍵字 | 概述 |
---|---|
package | 包名,只限於邏輯上的管理,若自定義的查詢或函數位於同一包名,不管物理位置如何,都可以直接調用 |
import | 規則引用問題,導入類或方法 |
global | 全局變量 |
function | 自定義函數 |
queries | 查詢 |
rule end | 規則體 |
規則體語法結構
關鍵字 | 描述 |
---|---|
rule | 規則開始,參數是規則的唯一名稱 |
attributes | 規則屬性,是rule與when之間的參數,為可選項 |
when | 規則條件部分,默認為true |
then | 規則結果部分 |
end | 當前規則結束 |
pattern(匹配模式)
規則體中LHS部分綁定變量基本上兩種形式:
一種:整個Fact變量的綁定
rule "rule1"
when
$customer:Customer(age>25,gender=='male')
then
....
end
另一種:約束條件屬性變量的綁定
rule "rule1"
when
$customer:Customer(age>25,$g:gender=='male')
then
....
end
約束連接
“&&”(and) "||"(or) ","(and)
contains 比較操作符:
語法:Object(field[Collection/Array] contains|not contains value)
memberOf 比較運算符:判斷某個Fact對象的某個字段是否在一個或多個集合中
語法:Object(fieldName memberOf|not memberOf value[Collection/Array])
matches比較運算符:用來對某個Fact對象的字段與標准的Java正則表達式進行相似匹配
語法:Object(fieldName matches|not matches "正則表達式")
soundslike比較運算符:用來檢查單詞是否具有與給定值幾乎相同的聲音(使用英語發音)
語法:Object(fieldName soundslike 'value')
str 比較運算符:檢查String字段是否以某一值開頭/結尾,還可以判斷字符串長度
語法:Object(fieldName str[startsWith|endsWith|length])
三、規則屬性
1.no-loop
默認值:false
類型:Boolean。
屬性說明:防止死循環,當規則通過update之類的函數修改了Fact對象時,可能使規則再次被激活,從而導致死循環。
2.ruleflow-group
默認值:N/A
類型:String
屬性說明:ruleflow-group分為rule、flow和group3個部分,分別代表規則、流程、分組,即常說的規則流。
3.lock-on-active
默認值:false
類型:Boolean
屬性說明:lock-on-active是指“鎖定活躍”
4.salience
默認值:0
類型:integer
屬性說明:規則體被執行的順序,每一個規則都有一個默認的執行shunxu,如果不設置sailence屬性,規則體的執行順序為由上到下。salience值可以是一個整數,也可以是個負數,值越大,執行順序越高,排名靠前。
5.enabled
默認值:true
類型:Boolean
屬性說明:指規則是否可以被執行,若規則體設置為enabled false,則規則體將視為永久不被激活
6.dialect
可能值:Java或Mvel
類型:String
屬性說明:用來定義規則中要使用的語言類型,支持Mvel和java兩種類型的語言
7.date-effective
默認值:N/A
類型:String、日期、時間
屬性說明:只有當前系統時間大於等於設置的時間或日期,規則才會被激活。在沒有設置該屬性的情況下,規則體不受時間限制。可接受日期格式“dd-MMM-yyyy" 如:date-effective “25-October-2019"
8.date-expires
默認值:N/A
類型:String、日期、時間
屬性說明:date-expires屬性與date-effective屬性相反,只有當前系統時間小於設置的時間或日期,規則才會激活 修改日期格式:通過 System。setProperty(“drools.dateformat","yyyy-MM-dd HH:mm:ss")
9.duration
默認值:無
類型:long
屬性說明:表示定時器,如果當前規則LHS部分為true,那么規則繼續執行;如果該屬性已經被棄用,那么通過新的屬性timer來控制
10.activation-group
默認值:N/A
類型:String
屬性說明:activation-group是指激活分組,通過字符串定義分組名稱,具有相同組名稱的規則體有且只有一個規則被激活,其他規則體的LHS部分仍然為true也不會再被執行。該屬性受salience屬性的影響,如當前規則文件中的其他規則未設計該屬性,則視為規則處於被激活狀態,並不受該屬性的影響。
11.agenda-group
默認值:無,需要通過Java設置
類型:String
屬性說明: agenda-group是議程分組,屬於另一種可控的規則執行方式,是指用戶可以通過配置agenda-group的參數來控制規則的執行,而且只有獲取焦點的規則才會被激活。
ks.getAgenda().getAgendaGroup("ag1").setFocus();//讓AgendaGroup分組為ag1的獲取焦點
12.auto-focus
默認值:false
類型:boolean
屬性說明:auto-focus屬性為自動獲取焦點,即當前規則是否被激活。如果一個規則被執行,那么認為auto-focus為true;如果單獨設置,一般結合agenda-group,當一個議程組未獲取焦點時,可以設置auto-focus來控制
13.timer
默認值:無
類型:與java定時器參數類型相似
屬性說明:timer是一個定時器,用來控制規則的執行時間,兩種寫法:
//第一種
timer(int:<initial delay> <repeat interval>?)
timer(int: 30s)
timer(int: 30s 5m)
//第二種
timer(cron: <cron expression>)
timer(cron: * 0/15 * * * ?)
四、中級語法
1.global全局變量
1.常量值是不能改變的
2.包裝類是不能改變的
3.類似javaBean、List類的操作是可以改變內容的,但內存地址不變
2.query查詢
以query開始、以end結束
package rules.rulesHello
import com.mufeng.rules.pojo.Person;
//"person age is 30 and name is 張三" 名稱
// (String $name) 參數 (多個可以用","分隔)
query "person age is 30 and name is 張三" (String $name)
person:Person(name==$name,age==30)
end
3.function函數
規則中函數有兩種形式:
一種:在規則中添加關鍵字function
package rules.isFunction
rule "function1"
when
then
System.out.println(function1("王二"));
end
function String function1(String name){
System.out.println("name:"+name);
return name;
}
另一種:import,引用java靜態方法
4.declare聲明
功能:1.聲明新類型,2.聲明元數據類型
package rules.rulesHello
declare Person1 extends com.mufeng.rules.pojo.Person //聲明 extends加繼承
type:String
end
rule "de1"
when
then
Person1 p=new Person1();
p.setName("張三");
p.setType("2");
insert(p);
end
rule "de"
when
$p:Person1(name=="張三")
then
System.out.println($p.getType());
System.out.println($p);
end
4.規則when
對象屬性有3中類型的限制:單值限制、復合值限制和多限制
單值限制:(name=="張三")
1.復合值限制in/not in
Person(className in ("一班","二班",$cn))
2.條件元素eval
eval(expression) :任何語義代碼,並返回一個boolean類型
3.條件元素not
判斷工作內存中是否存在某個值,如 not Person();
4.條件元素exists
與not相反,判斷工作內存中存在某個值,如 exists Person();
5.條件元素forall
與eval()功能相似,通過模式匹配對forall進行判斷,當完全匹配是,forall為true。
forall(p:Person(name=="張三") Person(this==p,age==30))
6.條件元素from
可以讓用戶指定任意的資源,用於LHS部分的數據匹配,也可以用來對集合進行遍歷,還可以用來對java服務進行訪問並就結果進行遍歷 如 from listFrom("張三",10) listFrom為靜態方法,返回list集合
7.條件元素collect
需要結合from來使用 from collect 用來匯總的
8.條件元素accumulate(功能強大)
允許規則迭代整個對象的集合,為每個元素定制執行動作,並在結束時返回一個結果對象,支持預定義的累積函數的使用,也可以使用其他內置函數,還可以使用自定義函數進行特殊化操作。
內置包括:average(平均值)、min(最小值)、max(最大值)、count(統計)、sum(求和)、collectList(返回List)、collectSet(返回HashSet)
inline的語法結構:
<result pattern> from accumulate(<source patterm>,init(<init code>),action(<action code>),reverse(<reverse code>),result(<result expression>))
自定義定制:新建 TestAccumulate並實現AccumulateFunction目錄為com/rulesAccumulate
9.條件元素規則繼承
與java相似,
rule "No2" extends "No1"
10.條件元素do對應多then同條件
rule "test"
when
$p:Person(name=="張三")
do[then03]
do[then03]
then
System.out.println("......");
then[then01]
System.out.println("******");
then[then03]
System.out.println("******");
end
1.使用do時,do的參數與then的參數必須有對應關系。
2.then可以不與do成對出現
3.使用do時,do后的參數在RHS中是必須要存在的,參數是一個zhizhen。
4.使用修改時,在非update情況下,then部分都會被執行。
5.使用修改時,在update情況下,then部分是有優先級的,是根據do的順序控制的,但沒有參數的then可能會改變其他的RHS部分。
6.使用do時,順序控制是至關重要的。
7.無參數的then,優先級可能會低於指定的do。
8.do只能在其他條件元素之后使用。
5.規則then
操作命名:
update(Fact事實對象)
insert(new Object())
insertLogical(new Object())
delete(handle)
modify(<fact-expression>){
<expression>[,<expression>]*
}
modify($p){
setAge(50),
setName("李四")
}
drools.halt():立即終止規則執行。
drools.geWorkingMemory():返回WorkingMemory對象。
drools.setFocus(String s):將焦點放在指定的議程組上。
drools.getRule().getName():返回規則的名稱。
drools.getTule():返回與當前正在執行的規則匹配的數組,並且為drools.getActivation()提供相應的激活
6.kmodule配置說明
kmodule.xml文件放到src/main/resources/META-INF/文件夾下
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="rules" packages="rules.rulesHello">
<ksession name="testhelloWorld"/>
</kbase>
<kbase name="query" packages="rules.isQuery">
<ksession name="isQuery"/>
</kbase>
<kbase name="function" packages="rules.isFunction">
<ksession name="isFunction"/>
</kbase>
</kmodule>
五、KieSession狀態
有狀態的KieSession:
需要清理KieSession的狀態,調用dispose()方法,如果在調用規則時不調用dispose()方法,則KieSession.insert(Object)會產生迭代方法插入的(笛卡爾積)
無狀態的StatelessKieSession
execute()默認調用dispose()方法
六、Drools高級用法
1.決策表
注釋行:package | 包路徑 | ||
---|---|---|---|
關鍵字 | RuleSet | rulesTwo.isXls | |
關鍵字 | RuleTable 測試規則 | ||
關鍵字 | CONDITION | ACTION | |
條件區 | |||
條件區 | eval(true); | System.out.println("$param"); | |
條件注釋行 | |||
規則值說明 | 測試規則_7 | ||
規則值說明 | 測試規則_8 | ||
規則值說明 | 測試規則_9 |
1.RuleSet和drl文件中package功能是一樣的,為必填項
2.RuleTable和drl文件中規則名稱的功能是一樣的,為必填項
3.CONDITION和規則體中LHS部分功能是一樣的,為必填項
4.ACTION和規則體中RHS部分功能是一樣的,為必填項
檢查決策表生成drl文件是否正確
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
占位符:和 1、$2
2.DSL領域語言(略)
3.規則模板
cheese.xls
年齡 | className | log | ||
50 | 一班 | 1 | ||
40 | 二班 | 2 | ||
30 | 三班 | 3 | ||
20 | 四班 | 4 | ||
cheese.drt
template header
age
className
package rulesTwo.isDrt;
import com.mufeng.rules.pojo.Person;
template "cheesefans"
rule "cheese fans_@{row.rowNumber}"
no-loop true
when
$p:Person(age==
規則模板文件以template header開頭,以end template結尾 age表示Excel文件的列 相當於占位符
<kbase name="isDrt" packages="rulesTwo.isDrt">
<ruleTemplate dtable="rulesTwo/isDrt/cheese.xls" template="rulesTwo/isDrt/cheese.drt" row="3" col="2"/>
<ksession name="isDrt"/>
</kbase>
row="3" 從第三行取數據 col="2" 從第二行取數據
第二種獲取方法:
4.規則流(略)
5.Drools事件監聽
RuleRuntimeEvenListener,AgendaEventListener,ProcessEventListener3個接口
七、Workbench
1.安裝與配置
1.安裝jdk
2.安裝tomcat
http://tomcat.apache.org/download-70.cgi
3.下載Workbench的war包,http://www.drools.org/download/download.html
安裝說明:
(1)將war包放在webapps/目錄下,並改名為kie-wb.war
(2)將下列jar復制到TOMCAT_HOME/lib中:
btm-2.1.4.jar
btm-tomcat55-lifecycle-2.1.4.jar
h2-1.3.161.jar
jta-1.1.jar
slf4j-api-1.7.2.jar
slf4j-jdk14-1.7.2.jar
log4j-api-2.1.jar
log4j-slf4j-impl-2.1.jar
<dependency>
<groupId>org.codehaus.btm</groupId>
<artifactId>btm</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.btm</groupId>
<artifactId>btm-tomcat55-lifecycle</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.161</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.1</version>
</dependency>
(3)在TOMCAT_HOME/conf目錄下,新建btm-config.properties(每個語句后面不能有空格)
bitronix.tm.serverId=tomcat-btm-node0
bitronix.tm.journal.disk.logPart1Filename=${btm.root}/work/btm1.tlog
bitronix.tm.journal.disk.logPart2Filename=${btm.root}/work/btm2.tlog
bitronix.tm.resource.configuration=${btm.root}/conf/resources.properties
在TOMCAT_HOME/conf下,新建resources.properties,
resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
resource.ds1.uniqueName=jdbc/jbpm
resource.ds1.minPoolSize=10
resource.ds1.maxPoolSize=20
resource.ds1.driverProperties.driverClassName=org.h2.Driver
resource.ds1.driverProperties.url=jdbc:h2:file:~/jbpm
resource.ds1.driverProperties.user=sa
resource.ds1.driverProperties.password=
resource.ds1.allowLocalTransactions=true
(4)在TOMCAT_HOME/bin目錄下,新建setenv.sh
CATALINA_OPTS="-Xmx512M - XX:MaxPermSize=512m -Dbtm.root=$CATALINA_HOME
-Dbitronix.tm.configuration=$CATALINA_HOME/conf/btm-config.properties
-Djbpm.tsr.jndi.lookup=java:comp/env/TransactionSynchronizationRegistry
-Djava.security.auth.login.config=$CATALINA_HOME/webapps/kie-web/WEB-INF/classes/login.config
-Dorg.jboss.logging.provider=jdk
-Dorg.jbpm.cdi.bm=java:comp/env/BeanManager
-Dorg.guvnor.m2repo.dir=/root/.m2/repository
-Dorg.kie.demo=false
-Dorg.kie.example=false"
(5)配置JEE security
把下面3個jar包放到TOMCAT_HOME/lib下
<dependency>
<groupId>javax.security.jacc</groupId>
<artifactId>javax.security.jacc-api</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-tomcat-integration</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
(6)在TOMCAT_HOME/conf/server.xml的Host節點最后添加
<Value className="org.kie.integration.tomcat.JACCValve"/>
(7)編輯TOMCAT_HOME/conf/tomcat-users.xml,添加‘analyst'或’admin‘角色,添加KIE-WB相應的用戶
<role rolename="admin"/>
<role rolename="analyst"/>
<user username="kie" password="kie" roles="admin"/>
<user username="kie-analyst" password="kie-analyst" roles="analyst"/>
(8)啟動tomcat,訪問 “8080/kie-wb" perfect