Drools内部功能详细介绍
来源:互联网 发布:淘宝双肩包店推荐 编辑:程序博客网 时间:2024/06/05 07:50
规则文件
在 Drools 当中,一个标准的规则文件就是一个以“.drl”结尾的文本文件,由于它是一个标准的文本文件,所以可以通过一些记事本工具对其进行打开、查看和编辑。规则是放在规则文件当中的,一个规则文件可以存放多个规则,除此之外,在规则文件当中还可以存放用户自定义的函数、数据对象及自定义查询等相关在规则当中可能会用到的一些对象。
一个标准的规则文件的结构代码清单:
除package之外,其它对象在规则文件中的顺序是任意的,也就是说在规则文件当中必须要有一个package声明,同时package 声明必须要放在规则文件的第一行,规则文件当中的package和Java语言当中的package有相似之处,但不完全相同。在Java当中package的作用是用来对功能相似或相关的文件放在同一个package下进行管理,这种package管理既有物理上Java文件位置的管理也有逻辑上的文件位置的管理,在Java当中这种通过package管理文件要求在文件位置在逻辑上与物理上要保持一致;但在Drools 的规则文件当中package 对于规则文件中规则的管理只限于逻辑上的管理,而不管其在物理上的位置如何,这点是规则与Java文件的package的区别。
对于同一package下的用户自定义函数、自定义的查询等,不管这些函数与查询是否在同一个规则文件里面,在规则里面是可以直接使用的,这点和 Java 的同一package里的 Java 类调用是一样的。
规则语言
一个规则可以包含三个部分:唯有attributes部分是可选的,其他都是必填信息:
定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等
条件部分:
即LHS,定义当前规则的条件,如when Message(); 判断当前workingMemory中是否存在Message对象。
结果部分:
即RHS,这里可以写普通java代码,即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用
条件部分:
LHS 部分是由一个或多个条件组成,条件又称之为 pattern(匹配模式),多个 pattern 之间用可以使用 and 或 or 来进行连接,同时还可以使用小括号来确定 pattern 的优先级
对于一个 pattern 来说“绑定变量名”是可选的,如果在当前规则的 LHS 部分的其它的 pattern 要用到这个对象,那么可以通过为该对象设定一个绑定变量名来实现对其引用,对于绑定变量的命名,通常的作法是为其添加一个“$”符号作为前缀,这样可以很好的与 Fact的属性区别开来;绑定变量不仅可以用在对象上,也可以用在对象的属性上面,命名方法与对象的命名方法相同;“field 约束”是指当前对象里相关字段的条件限制,
规则中 LHS 部分单个pattern (模式) 的情形。
规则中“$customer”是就是一个绑定到 Customer 对象的“绑定变量名”,该规则的 LHS 部分表示,要求 Fact 对象必须是 Customer 类型,该条件满足了那么它的 LHS 会返回 true。
下面这种写法就是包含两种pattern(模式) :
rule "rule1" when $customer:Customer(age>20,gender=='male') Order(customer==$customer,price>1000) then ....end
简单说明一下上面的代码
第一个:pattern(模式) 有三个约束
1、 对象 类型必须是 Cutomer;
2、Cutomer 的 age 要大于 20
3、Cutomer 的 gender 要是 male
第二个:pattern(模式) 有三个约束
1、 对象类型必须是 Order;
2、 Order 对应的 Cutomer 必须是前面的那个 Customer
3、 当前这个 Order 的price 要大于 1000
这两个 pattern 没有符号连接,在 Drools 当中在 pattern 中没有连接符号,那么就用 and 来作为默认连接,所以在该规则的 LHS 部分 中两个pattern(模式)只有都满足了才会返回 true。默认情况下,每行可以用“;”来作为结束符(和 Java 的结束一样),当然行尾也可以不加“;”结尾。
约束连接
对于对象内部的多个约束的连接,可以采用“&&”(and)、“||”(or)和“,”(and)来实现
这三个连接符号如果没有用小括号来显示的定义优先级的话,那么它们的执行顺序是:“&&”(and)、“||”(or)
表面上看“,”与“&&”具有相同的含义,但是有一点需要注意,“,”与“&&”和“||”不能混合使用,也就是说在有“&&”或“||”出现的 LHS 当中,是不可以有“,”连接符出现的,反之亦然
Drools提供了十二中类型比较操作符:如果进行常量比较,必须通过eval(条件)或者对象引用比较对象属性,不能单独使用,这语法与java是一样的
>|<,>=|<=,==|!= 这几个不多说啦
contains| not contains
memberOf | not memberOf
matches | not matches
下面说明一下后面6种的含意
contains:比较操作符 contains 是用来检查一个 Fact 对象的某个字段(该字段要是一个 Collection 或是一个 Array 类型的对象)是否包含一个指定的对象
语法格式:
Object( field[Collection/Array] contains value)
Contains.drl写法
package rules.testwrodimport com.drools.test.Personimport com.drools.test.Schoolrule test001 when $s:School(); $p:Person(name contains $s.name); then System.out.println("恭喜你,成功的使用了 contains");end
JavaAPI写法
package com.drools.test;import org.kie.api.KieServices;import org.kie.api.runtime.KieContainer;import org.kie.api.runtime.KieSession;import org.kie.api.runtime.rule.FactHandle;public class TestWrod{ public static void main(String[] args){ KieServices kss = KieServices.Factory.get(); KieContainer kc = kss.getKieClasspathContainer(); KieSession ks =kc.newKieSession("session"); School school=new School(); school.setCount(50); school.setName("一班"); Person person=new Person("一班",30); FactHandle insert = ks.insert(person); ks.insert(school); int count = ks.fireAllRules(); System.out.println("总执行了"+count+"条规则"); ks.dispose(); }}
contains只能用于对象的某个 Collection/Array类型的字段与另外一个值进行比较,作为比较的值可以是一个静态的值,也可以是一个变量(绑定变量或者是一个global对象),说的可能有点麻烦,小编在这里给大家再通俗的说一下,其实contains就是用来比较属性值是否与被比较值相同,但是这两个属性名是相同的。
not contains:not contains作用与 contains作用相反,not contains是用来判断一个Fact对象的某个字段(Collection/Array类型)是不是包含一个指定的对象,和 contains比较符相同,它也只能用在对象的 field当中,举例说明
Contains.drl写法
package rules.testwrodimport com.drools.test.Personimport com.drools.test.Schoolrule test001 when $s:School(); $p:Person(age not contains $s.count); then System.out.println("恭喜你,成功的使用了not contains");end
JavaAPI写法
package com.drools.test;import org.kie.api.KieServices;import org.kie.api.runtime.KieContainer;import org.kie.api.runtime.KieSession;import org.kie.api.runtime.rule.FactHandle;public class TestWrod{ public static void main(String[] args){ KieServices kss = KieServices.Factory.get(); KieContainer kc = kss.getKieClasspathContainer(); KieSession ks =kc.newKieSession("session"); School school=new School(); school.setCount(50); school.setName("一班"); Person person=new Person("一班",30); FactHandle insert = ks.insert(person); ks.insert(school); int count = ks.fireAllRules(); System.out.println("总执行了"+count+"条规则"); ks.dispose(); }}
结果一定是我们想要的,是因为Person中的属性是age而School的属性是count,就算值相同,属性名不同 在not contains下是成立的。
memberOf:memberOf是用来判断某个Fact对象的某个字段是否在一个集合(Collection/Array)当中,用法与 contains有些类似,但也有不同
memberOf的语法如下:
Object(fieldName memberOf value[Collection/Array])
可以看到 memberOf中集合类型的数据是作为被比较项的,集合类型的数据对象位于memberOf操作符后面,同时在用 memberOf比较操作符时被比较项一定要是一个变量(绑定变量或者是一个 global对象),而不能是一个静态值。如何给全局变量赋值:ksession.setGlobal("list",list);举例说明
memberOf.drl文件
package rules.testwrodimport com.drools.test.Personglobal java.util.List list;rule test001 when $p:Person(name memberOf list); then System.out.println("恭喜你,成功的使用了 memberOf");end
JavaAPI写法
package com.drools.test;import org.kie.api.KieServices;import org.kie.api.runtime.KieContainer;import org.kie.api.runtime.KieSession;import org.kie.api.runtime.rule.FactHandle;public class TestWrod{ public static void main(String[] args){ KieServices kss = KieServices.Factory.get(); KieContainer kc = kss.getKieClasspathContainer(); KieSession ks =kc.newKieSession("session"); List list=new ArrayList(); list.add("张三"); list.add("李四"); list.add("王五"); list.add("赵六"); Person person=new Person("张三",50); ks.setGlobal("list",list); FactHandle insert = ks.insert(person); ks.insert(school); int count = ks.fireAllRules(); System.out.println("总执行了"+count+"条规则"); ks.dispose(); }}
结果肯定是我们想要的了
not memberOf:该操作符与 memberOf作用洽洽相反,是用来判断Fact对象当中某个字段值是不是中某个集合(Collection/Array)当中。小编这里就不给读者举例说明,有兴趣的读者可以自己尝试一下。
matches:matches是用来对某个 Fact 的字段与标准的 Java 正则表达式进行相似匹配,被比较的字符串可以是一个标准的 Java 正则表达式,有一点小编要提醒读者注意,那就是正则表达式字符串当中不用考虑“\”的转义问题。
语法如下:
Object(fieldName matches “正则表达式”)
举例说明
Matches.drl
package rules.testwrodimport com.drools.test.Personrule test001 when $p:Person(name matches "张.*"); then System.out.println("恭喜你,成功的使用了 matches");end
JavaAPI写法
package com.drools.test;import org.kie.api.KieServices;import org.kie.api.runtime.KieContainer;import org.kie.api.runtime.KieSession;import org.kie.api.runtime.rule.FactHandle;public class TestWrod{ public static void main(String[] args){ KieServices kss = KieServices.Factory.get(); KieContainer kc = kss.getKieClasspathContainer(); KieSession ks =kc.newKieSession("session"); Person person=new Person("张三",30); FactHandle insert = ks.insert(person); ks.insert(school); int count = ks.fireAllRules(); System.out.println("总执行了"+count+"条规则"); ks.dispose(); }}
结果如下:
小编这里补充几点:简单来说就是模糊查询,语法是不能是“*.三”这样的语法是错误的。
该规则是用来查找所有Person对象的 name属性是不是以“张”字开头,如果满足这一条件那么就将该Person对象的 name 属性打印出来
not matches:与matches作用相反,是用来将某个Fact的字段与一个Java标准正则表达式进行匹配,看是不是能与正则表达式匹配。 小编这里就不多写做例子了,建议读者要自己试一下,体验一下结果
语法扩展部分
访问List数据结构
$customer.accounts[3]等同于$customer.getAccounts(3)
访问Map数据结构
$customerMap["123"]等同于$customerMap.get["123"]
小编想和读者说的话
小编也是加了少群的,研究Drools这一块技术,遇到了很多难题,很多技术问题,小编不敢说这文章是写的最好的,只是做一个技术分享,之前也有写过博客,但遇到一些事让小编有些心寒,所以将博客删除了,小编真的不是来装大神装B的,只是将自己会的一些技术分享出来,让初学者少走一些弯路,这技术比较冷门,所以资料少的可怜
经过小编的不懈努力,结合了自己的认知和笔记,用时两周将些文档编辑成功,读者如果心疼小编,就给一些辛苦费啥的,小编后续会继续努力将底层实现和算法的知识也写进来的
文章是不可编辑的,读者要是看到哪里有问题或出错的地方,可随时与小编联系,小编的QQ是448998253 邮箱是kangzuguan@qq.com
下面是小编的微信转帐二维码,小编再次谢谢读者的支持,小编会更努力的
- Drools内部功能详细介绍
- drools介绍
- drools介绍
- Drools介绍
- GridView功能详细介绍
- MDK功能详细介绍
- [Drools]JAVA规则引擎 -- Drools 详细说明
- DM9000寄存器功能详细介绍
- DM9000寄存器功能详细介绍
- DM9000寄存器功能详细介绍
- DM9000寄存器功能详细介绍
- DM9000寄存器功能详细介绍
- mysql分区功能详细介绍
- VtigerCRM 模块功能详细介绍
- Xcode9:最新功能详细介绍
- drools学习1--介绍
- drools入门介绍
- Drools规则引擎介绍一
- 百度快照多久更新一次?
- 结构体排序(优先级)
- python实现桶排序
- Redis为什么用跳表而不用平衡树?
- php操作数组的方法
- Drools内部功能详细介绍
- B1030. 完美数列(25)
- JavaScript 开发的45个经典技巧
- 使用Navigation timing api测试android webview性能
- 手机App通过http协议从web服务器上获取json格式的数据
- spring scheduled定时任务
- java入门之“Hello World”
- 浅谈HTTP中Get与Post的区别
- Android Studio中使用NDK/JNI