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