您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
Drools内部功能详细介绍
 
   次浏览      
 2018-3-26 
 
编辑推荐:
本文来自于csdn,Drools(JBoss Rules )具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。

规则文件

在 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 类型的对象)是否包含一个指定的对象

语法格式:

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

matches:matches 是用来对某个 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"]

 

   
次浏览       
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析