Drools内部功能详细介绍

规则文件

    在 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对象的方法来操作应用
条件部分:

    条件部分又被称之为 Left Hand Side,简称为 LHS,下文当中,如果没有特别指出,那么所说的 LHS 均指规则的条件部分,在一个规则当中 when 与 then 中间的部分就是 LHS 部分。在 LHS 当中,可以包含 0~n 个条件,如果 LHS 部分没空的话,那么引擎会自动添加一 个 eval(true)的条件,由于该条件总是返回 true,所以 LHS 为空的规则总是返回 true。  


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.testwrod
import com.drools.test.Person
import com.drools.test.School
rule 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 containsnot contains作用与 contains作用相反,not contains是用来判断一个Fact对象的某个字段(Collection/Array类型)是不是包含一个指定的对象,和 contains比较符相同,它也只能用在对象的 field当中,举例说明

Contains.drl写法

package rules.testwrod
import com.drools.test.Person
import com.drools.test.School
rule 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中的属性是ageSchool的属性是count,就算值相同,属性名不同 在not contains下是成立的。

memberOfmemberOf是用来判断某个Fact对象的某个字段是否在一个集合(Collection/Array)当中,用法与 contains有些类似,但也有不同

memberOf的语法如下:

Object(fieldName memberOf value[Collection/Array])

可以看到 memberOf中集合类型的数据是作为被比较项的,集合类型的数据对象位于memberOf操作符后面,同时在用 memberOf比较操作符时被比较项一定要是一个变量(绑定变量或者是一个 global对象),而不能是一个静态值。如何给全局变量赋值:ksession.setGlobal("list",list);举例说明

memberOf.drl文件

package rules.testwrod

import com.drools.test.Person

global 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)当中。小编这里就不给读者举例说明,有兴趣的读者可以自己尝试一下。

 

matchesmatches是用来对某个 Fact 的字段与标准的 Java 正则表达式进行相似匹配,被比较的字符串可以是一个标准的 Java 正则表达式,有一点小编要提醒读者注意,那就是正则表达式字符串当中不用考虑“\”的转义问题。

语法如下:

Object(fieldName matches “正则表达式”)

举例说明 

Matches.drl

package rules.testwrod

import com.drools.test.Person

rule 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从入门到精通:可下载开源全套Drools教程

深度Drools教程不段更新中:


更多Drools实战陆续发布中………

扫描下方二维码关注公众号 ↓↓↓↓↓↓↓↓↓↓




  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Drools是一个基于规则引擎的开源项目,它允许开发人员以一种更具可读性、易于理解和维护的方式编写业务规则。Drools规则引擎可以将业务规则从应用程序中解耦出来,以便更改和更新规则而无需修改应用程序代码。Drools还提供了一个规则编辑器,使得非技术人员也能直接编辑规则。 Drools引擎基于Java语言开发,并遵循Java规范。它使用反射、动态代理、Rete算法等技术来实现规则匹配和执行。Drools支持多种规则类型,包括有序规则、循环规则、递归规则、约束规则等。 Drools的核心原理是基于规则引擎实现的。规则引擎在运行时将一组规则应用于一组事实,以确定哪些规则适用于哪些事实。Drools使用Rete算法来匹配规则和事实,并使用规则的条件部分来判断规则是否适用于给定的事实。如果一个规则适用于一个事实,那么该规则的动作部分将被执行。 Drools还提供了一些高级功能,如规则流程、决策表、事件处理等。规则流程允许用户将规则序列化为流程,以便更好地描述复杂的业务流程。决策表是一个电子表格,其中包含规则和数据,可以用来自动生成规则。事件处理允许用户定义和处理事件,以便更好地响应业务需求。 总之,Drools是一种灵活、高效的规则引擎,可以帮助开发人员更好地管理和维护业务规则,并提高应用程序的可扩展性和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值