drools笔记.docx
- 文档编号:7051875
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:19
- 大小:438.58KB
drools笔记.docx
《drools笔记.docx》由会员分享,可在线阅读,更多相关《drools笔记.docx(19页珍藏版)》请在冰豆网上搜索。
drools笔记
笔记
一、规则的编译和运行
在drools当中,规则的编译和运行要通过drools提供的各种API来实现,这些API总体来讲可以分为三类:
规则编译、规则收集和规则的执行。
完成这些工作的API主要有KnowledgeBuilder、KnowledgeBase、StatefulKnowledgeSession、StatelessKnowledgeSession、、等,它们起到了对规则文件进行收集、编译、查错,插入fact、设置global、执行规则或规则流等作用。
1、KnowledgeBuilder
KnowledgeBuilder的作用是在业务代码中收集已经编写好的规则,然后对这些规则文件进行编译,最终产生一批编译好的规则包(KnowledgeBuilder)给其它的应用程序使用。
KnowledgeBuilder在编译规则的时候可以通过其提供的hasErrors()方法得到编译规则过程中发现规则是否有错误,如果有的话通过其提供的getErrors()方法将错误打印出来,以帮助我们找到规则当中错误的信息。
通过KnowledgeBuilder编译的规则文件的类型可以有很多种,如drl,dslr文件或xls文件等。
产生的规则包可以是具体的规则文件形成的,也可以是规则流(ruleflow)文件形成的,在添加规则文件时,需要通过使用ResourceType的枚举值来制定规则文件类型;同时在指定规则文件的时候drools还提供了一个名为ResourceFactory的对象,通过该对象可以实现从Classpath、URL、File、ByteArray、Reader或注入XLS的二进制文件里添加载规则。
在规则文件添加完成后,可以通过使用hasErrors()方法来检测已添加进去的规则当中有没有错误,如果不通过该方法检测错误,那么如果规则当中存在错误,最终来使用的时候也会将错误抛出。
2、KnowledgeBase
KnowledgeBase是Drools提供的用来收集应用当中知识(knowledge)定义的知识库对象,在一个KnowledgeBase当中可以包含普通的规则(rule)、规则流(ruleflow)、函数定义(function)、用户自定义对象(typemodel)等。
KnowledgeBase本身不包含任何业务数据对象(fact对象),业务对象都是插入到由KnowledgeBase产生的两种类型的session对象当中(StatefulKnowledgeSession和StatelelessKnowledgeSession),通过session对象可以出发规则执行或开始一个规则流执行。
创建一个KnowledgeBase要通过KnowledgeBaseFactory对象提供的newKnowledgeBase()方法来实现,这其中创建的时候还可以为其指定一个KnowledgeBaseConfiguration对象,KnowledgeBaseConfiguration对象是一个用来皴法规则引擎运行时相关环境参数定义的配置对象。
创建一个KnowledgeBaseConfiguration对象的方法也是使用KnowledgeBaseFactory,使用的是其提供的newKnowledgeBaseConfiguraton()方法该方法创建好的KnowledgeBaseConfiguration对象默认情况下会加载drools-core-5.0.1.jar包下META-INF/drools.default.rulebase.conf文件里的规则运行环境配置信息,加载完成后,我们可以在代码中对这些默认的信息重新赋值,以覆盖加载的默认值。
除了这种方式创建KnowledgeBaseConfiguration方法之外,我们还可以为其显示的指定一个properties对象,在该对象中设置好需要覆盖默认值的相关属性定的值,然后再通过newKnowledgeBaseConfiguration(Propertiesprop,ClassLoaderloader)方法创建一个KnowledgeBaseConfiguration对象。
该方法当中的第一个参数就是我们设置Properties对象,第二个参数用来加载META-INF\drools.default.rulebase.conf文件的ClassLoader,因为该文件在ClassPath下,所以采用的是ClassLoader方法进行加载,如果不指定这个参数,那么就取默认的ClassLoader对象,如果两个参数都是null,那么就和newKnowledgeBaseConfiguration()方法的作用相同了。
KnowledgeBase创建完成之后,接下来我们可以将钱买你使用KnowledgeBuilder生成的KnowledgePackage的集合添加到Knowledge当中,以备使用。
3、StatefulKnowledgeSession
规则编译完成之后,接下来就需要使用一个API使编译好的规则包文件在规则引擎当中运行起来。
在drools5当中提供了两个对象与规则引擎进行交互:
StatefulKnowledgeSession和StatelessKnowledgeSession。
StatefulKnowledgeSession对象是一种最常用的与规则引擎进行交付的方式,它可以与规则引擎建立一个持续的交互通道,在推理计算的过程当中可能会多次出发同一数据集。
在用户的代码当中,最后使用完StatefulKnowledgeSession对象之后,一定要调用其dispose()方法以释放相关内存资源。
StatefulKnowledgeSession可以接受外部插入(insert)的业务数据—也叫fact,一个fact对象通常是一个普通的java的POJO一般它们会有若干个属性,每一个属性都会对应getter和setter方法,用来对外提供数据大的设置和访问。
一般来说,在drools规则引擎当中,fact所承担的作用就是将规则当中要用到的业务数据从应用当中传入进来,对于规则当中产生的数据及状态的变化通常不用fact传出。
如果在规则当中需要有数据传入,那么可以通过在StatefulKnowledgeSession当中设置global对象来实现,一个global对象也是一个普通的java对象,在向StatefulKnowledgeSession当中设置global对象时不用insert方法而用setGlobal方法实现。
创建一个StatefulKnowledgeSession要通过KnowledgeBase对象来实现。
privatestaticvoidmethod1(){
KnowledgeBuilderkbuilder=KnowledgeBuilderFactory
.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("TEST.drl",
StatefulKnowledgeSessionDemo.class),ResourceType.DRL);
Collection
KnowledgeBaseConfigurationkbassConf=KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
kbassConf.setProperty("org.drools.sequential","true");
KnowledgeBasekbase=KnowledgeBaseFactory.newKnowledgeBase(kbassConf);
kbase.addKnowledgePackages(coll);
StatefulKnowledgeSessionsksess=kbase.newStatefulKnowledgeSession();
//设置一个global对象
sksess.setGlobal("globalTest",newObject());
//插入一个fact对象
sksess.insert(newObject());
sksess.fireAllRules();
sksess.dispose();
}
规则完整的运行处理过程:
首先需要通过使用KnowledgeBuilder将相关的规则文件进行编译,产生对应的KnowledgePackage集合,接下来再通过KnowledgeBase把产生的KnowledgePackage集合收集起来,最后再产生StatefulKnowledgeSession将跟规则当中需要使用的fact对象插入进去、将规当中需要用到的global设置进去,然后调用fireAll()方法触发所有的规则执行,最后调用dispose()方法将内存资源释放。
4、StatelessKnowledgeSession的作用与StatefulKnowledgeSession相仿,它们都是用来接收业务数据、执行规则的。
事实上,StatelessKnowledgeSession对StatefulKnowledgeSession做了包装,使得在使用StatelessKnowledgeSession对象时不需要再调用dispose()方法释放内存资源了。
因为StatelessKnowledgeSession本身所具有的一些特性,决定了它的使用有一定的局限性。
在使用StatelessKnowledgeSession时不能进行重复插入fact的操作、也不能重复的调用fireAllRules()方法来执行所有的规则,对应这些要完成的工作在StatelessKnowledgeSession当中只有execute(…)方法,通过这个方法可以实现插入所有的fact滨崎额可以同时执行所有的规则或规则流,事实上也就是在执行execute()方法的时候就在StatelessKnowledgeSession内部执行了insert()方法、fireAllRules()方法和dispose()方法。
privatestaticvoidmethod1(){
KnowledgeBuilderkbuilder=KnowledgeBuilderFactory
.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("text.drl",
StatelessKnowledgeSessionDemo.class),ResourceType.DRL);
Collection
KnowledgeBaseConfigurationkconf=KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
kconf.setProperty("org.drools.sequential","true");
KnowledgeBasekbase=KnowledgeBaseFactory.newKnowledgeBase(kconf);
kbase.addKnowledgePackages(coll);
StatelessKnowledgeSessionksession=kbase
.newStatelessKnowledgeSession();
ArrayListlist=newArrayList();
list.add(newObject());
list.add(newObject());
ksession.execute(list);
}
StatelessKnowledgeSession当中的对象放到这个ArrayList当中,将这个ArrayList作为参数传给execute()方法,这样在StatelessKnowledgeSession内部会对这个ArrayList进行迭代,去除其中的每一个Element,将其作为fact,调用StatelessKnowledgeSession对象内部的StatefulKnowledgeSession对象的insert()方法将产生得而fact逐个插入到StatefulKnowledgeSession当中,然后调用StatefulKnowledgeSession的fireAllRules()方法,最后执行dispose()方法释放内存资源。
在上述代码中,如果我们要插入的fact就是这个arraylist而不是它内部的Element那该怎么处理?
在StatelessKnowledgeSession当中,还提供了execute(Commandcmd)的方法,在该方法中通过CommandFactory可以创建各种类型的Command,比如前面的需求要直接将这个ArrayList作为一个fact插入,那么就可以采用CommandFactory.newInsert(Objectobj)来实现。
如果需要通过StatelessKnowledgeSession设置global的话,可以使用CommandFactory.newSetGolbal(key,Objectobg)来实现;如果既要插入若干个fact,又要设置相关的global,那么可以将CommandFactory产生的Command对象放在一个Collectiond当中,然后再通过CommandFactory.newBatchExecution(Collectioncoll)方法来实现。
privatestaticvoidmethod2(){
KnowledgeBuilderkbuilder=KnowledgeBuilderFactory
.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("test.drl",
StatelessKnowledgeSessionDemo.class),ResourceType.DRL);
Collection
KnowledgeBaseConfigurationkbasecon=KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
kbasecon.setProperty("org.drools.sequential","true");
KnowledgeBasekbase=KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kpackage);
StatelessKnowledgeSessionsksession=kbase
.newStatelessKnowledgeSession();
ArrayList
list.add(CommandFactory.newInsert(newObject()));
list.add(CommandFactory.newInsert(newObject()));
list.add(CommandFactory.newSetGlobal("key1",newObject()));
list.add(CommandFactory.newSetGlobal("key1",newObject()));
sksession.execute(CommandFactory.newBatchExecution(list));
}
5、Fact对象
Fact是指在drools规则应用当中,将一个普通的javabean插入到规则的workingmemory当中后的对象。
规则可以对fact对象进行任意的读写操作,党一个javaban插入workingmemory当中编程fact之后,fact对象不是对原来打的javabean队形进行Clon,而是原来javabean对象的引用。
规则在进行计算的时候需要用到应用系统当中的数据,这个数据设置在fact对象当中,然后将其插入到规则的workingMemory当中,这样在规则当中就可以通过对fact对象数据的读写,从而实现对应用数据的读写操作。
一个fact对象通常是一个具有getter和setter方法的pojo对象,通过这些getter和setter方法可以方便的实现对fact对象的读写操作,所以我们可以简单的把fact对象理解为规则与应用系统数据交互的桥梁和通道。
当fact对喜爱那个插入到workingmemory当中后,会与当前workingmemory所有的规则进行匹配,同事返回一个FactHandler堆对象。
FactHandler对象是插入到WorkingMemory当中fact对象的引用句柄,通过FactHandler对象可以是想对对应的Fact对象的删除及修改等操作
二、规则
学习drools规则语法的目的是为了在应用当中帮助我们解决实际的问题,所以学会领过的在给I则当中使用就显得尤为重要。
本章的内容包括规则的基本的约束部分语法讲解(LHS)、规则动作执行部分语法讲解及语法讲解及规则的各种属性介绍。
1、规则文件
在drools当汇总,一个标准打的规则文件是以“.drl”结尾的文本文件,由于它是一个标准的文本文件,所以可以通过一些记事本工具对其进行打开、查看和编辑。
规则是放在规则文件当中的,一个规则文件可以存放多个规则,除此之外,在规则文件当中还可以存放用户自定义的函数、数据对象及自定义查询等相关的规则当中可能会用到的一些对象。
模板:
Packagepackage-name
Imports
Globals
Functions
Queries
Rules
对于一个规则文件而言,首先声明package是必须的,除package之外,其他对象在规则文件中的顺序是任意的,也就是说在规则文件当中必须要有一个package声明,同时package声明必须要放在规则文件的第一行。
规则问阿静当中的package和java语言当中的package有相似之处,也有不同之处。
在java当中package的作用是用来对功能相似的或相关的文件放在同一个package下进行管理,这种package管理既有物理上java文件位置的管理也有逻辑上的文件位置的管理,在java当中这种通过package管理文件要求文件位置在逻辑上和物理上保持一致;在drools的规则文件当中package对于规则文件中的规则的管理只限于逻辑上的管理,而不管其在物理上的位置如何,这点事规则与java文件的package的区别。
对于同一个package下的用户自定义的函数、自定义的查询等,不管这些函数或查询是否在同一个规则文件里面,在规则里面是可以直接使用的,这点和java的同一个package里的java类的调用时一样的。
2、规则语言
规则是在规则文件当中编写,所以要编写一个规则首先需要先创建一个存放规
规则文件。
一个规则文件可以存放若干个规则,每一个规则通过规则名称来进行标识。
Rule“name”
Attributes
When
LHS
Then
RHS
End
从上述可以看出:
一个规则通常包含三个部分:
属性部分(attributes)、条件部分(LHS)和结果部分。
对于一个完整的规则来说,这三个部分都是可选的。
条件部分
条件部分又被称之为LeftHandSide,简称为LHS。
在一个规则当汇总when和then中间的部分就是LHS部分。
在LHS当中,可以包含0~n个条件,如果LHS条件部分为空的规则总是返回true。
rule"name"
when
eval(true)
then
end
LHS部分是由一个或多个条件组成,条件又称之为pattern(匹配模式),多个pattern之间用可以使用and或or来进行连接,同时还可以使用小括号来确定pattern的优先级。
[绑定变量名:
]Object([field约束])
对于一个pattern来说,“绑定变量名”是可选的,如果在党建规则的LHS部分的其他的pattern要用到这个对象,那么可以通过为该对象设定一个绑定变量名来实现对其引用,对于绑定变量名的命名,通常的做法是为其添加一个“$”符号作为前缀,这样可以很好的与fact对象的输习惯区别开来;绑定变量不仅可以用在对象上,也可以同在对象的属性上面,命名方法与对象的命名方法相同;”field约束”是指当前对象里面的相关字段的条件的条件限制。
rule"name"
when
$customer:
Customer()
then
End
以上代码当中“$customer”是就是一个绑定到Customer对象的“绑定变量名”,该规则的LHS部分表示,要求fact对象必须是Customer雷系ing,该条件满足了那么它的LHS会返回true
rule"name"
when
$customer:
Customer(age>20,gender=='male')
Order(customer==$customer,price>1000)
then
End
以上代码中包含了两个pattern,第一个pattern有三个约束,分别是:
对象类型必须是Customer;同时Customer的age要大于20且gender要是male;第二个pattern也有三个约束,分别是:
对象类型必须是Order,同时Order对应的Customer必须是前面那个Customer且当前这个Order的price要大于1000.在这两个pattern没有符号链接,在drools当中在pattern中没有连接符号,那么就用and来作为默认连接,所以在该规则的LHS部分中两个pattern只有都满足了才会返回true。
默认情况下,每行都可以用”;“来作为结束符,当然行尾也可以不以”;“结尾。
约束连接
对于对象内部的多个约束的连接,可以采用”&&“(and)、”||“(or)和”,“(and)来实现。
三个连接符如果没有用小括号来显示的定义优先级的话,那么他们的执行顺序是:
”&&”,”||”,”,”。
在有”&&“或”||“出现的LHS当中,是不可以有”,“连接符出现的,反之亦然。
3、比较操作符
在drools当中提供了十二种类型的比较操作符,分别是:
>、>=、<、<=、==、!
=、contains、notcontains、
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- drools 笔记