这里没有翻译http://docs.jboss.org/drools/release/6.4.0.Final/drools-docs/html_single/index.html上的内容 而是参考了网上的一些博客,讲的很详细。摘录了一篇比较好的文章。

具体的使用例子见后面的wiki:

开始语法之前首先要了解一下drools的基本工作过程,通常而言我们使用一个接口来做事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是一样的,我们需要传递进去数据,用于规则的检查,调用外部接口,同时还可能需要获取到规则执行完毕后得到的结果。在drools中,这个传递数据进去的对象,术语叫 Fact对象。Fact对象是一个普通的java bean,规则中可以对当前的对象进行任何的读写操作,调用该对象提供的方法,当一个java bean插入到workingMemory中,规则使用的是原有对象的引用,规则通过对fact对象的读写,实现对应用数据的读写,对于其中的属性,需要提供getter setter访问器,规则中,可以动态的往当前workingMemory中插入删除新的fact对象。

规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件。

规则语法:

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行。特别的是,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分。同样的package下定义的function和query等可以直接使用。

比如:package com.drools.demo.point

import:导入规则文件需要使用到的外部变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法。

比如:

import com.drools.demo.point.PointDomain;

import com.drools.demo.point.PointDomain.getById;

rule:定义一个规则。rule "ruleName"。一个规则可以包含三个部分:

属性部分:定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。

条件部分,即LHS,定义当前规则的条件,如  when Message(); 判断当前workingMemory中是否存在Message对象。

结果部分,即RHS,这里可以写普通java代码,即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。

规则事例:

rule "name"

no-loop true

when

$message:Message(status == 0)

then

System.out.println("fit");

$message.setStatus(1);

update($message);

end

上述的属性中:

no-loop : 定义当前的规则是否不允许多次循环执行,默认是false,也就是当前的规则只要满足条件,可以无限次执行。什么情况下会出现一条规则执行过一次又被多次重复执行呢?drools提供了一些api,可以对当前传入workingMemory中的Fact对象进行修改或者个数的增减,比如上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操作会触发规则的重新匹配执行,可以理解为Fact对象更新了,所以规则需要重新匹配一遍,那么疑问是之前规则执行过并且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update之后,之前的修改都会生效。当然对Fact对象数据的修改并不是一定需要调用update才可以生效,简单的使用set方法设置就可以完成,这里类似于java的引用调用,所以何时使用update是一个需要仔细考虑的问题,一旦不慎,极有可能会造成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,如果本身的RHS部分有update等触发规则重新执行的操作,也不要再次执行当前规则。

但是其他的规则会被重新执行,岂不是也会有可能造成多次重复执行,数据紊乱甚至死循环?答案是使用其他的标签限制,也是可以控制的:lock-on-active true

lock-on-active true:通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版。当然该标签正规的用法会有其他的标签的配合,后续提及。

date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”,中英文格式相同,但是写法要用各自对应的语言,比如中文:"29-七月-2010",但是还是推荐使用更为精确和习惯的格式,这需要手动在java代码中设置当前系统的时间格式,后续提及。属性用法举例:date-expires "2011-01-31 23:59:59" // 这里我们使用了更为习惯的时间格式

date-effective:设置规则的生效时间,时间格式同上。

duration:规则定时,duration 3000   3秒后执行规则

salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序。

其他的属性可以参照相关的api文档查看具体用法,此处略。

规则的条件部分,即LHS部分:

when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列,比如

when

eval(true)

$customer:Customer()

$message:Message(status==0)

上述罗列了三个条件,当前规则只有在这三个条件都匹配的时候才会执行RHS部分,三个条件中第一个

eval(true):是一个默认的api,true 无条件执行,类似于 while(true)

$message:Message(status==0) 这句话标示的:当前的workingMemory存在Message类型并且status属性的值为0的Fact对象,这个对象通常是通过外部java代码插入或者自己在前面已经执行的规则的RHS部分中insert进去的。

前面的$message代表着当前条件的引用变量,在后续的条件部分和RHS部分中,可以使用当前的变量去引用符合条件的FACT对象,修改属性或者调用方法等。可选,如果不需要使用,则可以不写。

条件可以有组合,比如:

Message(status==0 || (status > 1 && status <=100))

RHS中对Fact对象private属性的操作必须使用getter和setter方法,而RHS中则必须要直接用.的方法去使用,比如

$order:Order(name=="qu")
  $message:Message(status==0 && orders contains $order && $order.name=="qu")

特别的是,如果条件全部是 &&关系,可以使用“,”来替代,但是两者不能混用

如果现在Fact对象中有一个List,需要判断条件,如何判断呢?

看一个例子:

Message {

int status;

List<String> names;

}

$message:Message(status==0 && names contains "网易" && names.size >= 1)

上述的条件中,status必须是0,并且names列表中含有“网易”并且列表长度大于等于1

contains:对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值。 

Drools提供了十二中类型比较操作符:

>  >=  <  <=  ==  !=  contains / not contains / memberOf / not memberOf /matches/ not matches

not contains:与contains相反。

memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象。

not memberOf:正好相反。

matches:正则表达式匹配,与java不同的是,不用考虑'/'的转义问题

not matches:正好相反。

规则的结果部分

当规则条件满足,则进入规则结果部分执行,结果部分可以是纯java代码,比如:

then

System.out.println("OK"); //会在控制台打印出ok

end

当然也可以调用Fact的方法,比如  $message.execute();操作数据库等等一切操作。

结果部分也有drools提供的方法:

insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定;

update:更新

modify:修改,与update语法不同,结果都是更新操作

retract:删除

RHS部分除了调用Drools提供的api和Fact对象的方法,也可以调用规则文件中定义的方法,方法的定义使用 function 关键字

function void console {

System.out.println();

StringUtils.getId();// 调用外部静态方法,StringUtils必须使用import导入,getId()必须是静态方法

}

Drools还有一个可以定义类的关键字:

declare 可以再规则文件中定义一个class,使用起来跟普通java对象相似,你可以在RHS部分中new一个并且使用getter和setter方法去操作其属性。

declare Address
 @author(quzishen) // 元数据,仅用于描述信息

@createTime(2011-1-24)
 city : String @maxLengh(100)
 postno : int
end

上述的'@'是什么呢?是元数据定义,用于描述数据的数据~,没什么执行含义

你可以在RHS部分中使用Address address = new Address()的方法来定义一个对象。

其他参考:

 

drools语法介绍的更多相关文章

  1. Swift翻译之-Swift语法入门 Swift语法介绍

    目录[-] Hello world - Swift 简单赋值 控制流 函数与闭包 对象和类 枚举与结构 协议和扩展 泛型 2014.6.3日,苹果公布最新编程语言Swift,Swift是一种新的编程语 ...

  2. flex弹性布局语法介绍及使用

    一.语法介绍 Flex布局(弹性布局) ,一种新的布局解决方案 可简单.快速的实现网页布局 目前市面浏览器已全部支持1.指定容器为flex布局 display: flex; Webkit内核的浏览器, ...

  3. freemarker语法介绍及其入门教程实例

    # freemarker语法介绍及其入门教程实例 # ## FreeMarker标签使用 #####一.FreeMarker模板文件主要有4个部分组成</br>####  1.文本,直接输 ...

  4. Drools 语法

    Drools 语法 规则语法 package: package 的名字是随意的,不必必须对应物理路径 import: 导入外部变量 规则的编译与运行要通过Drools 提供的各种API 来实现.API ...

  5. QSS类的用法及基本语法介绍

    QSS类的用法及基本语法介绍 目录 1. 何为Qt样式表2. 样式表语法基础3. 方箱模型4. 前景与背景5. 创建可缩放样式6. 控制大小7. 处理伪状态8. 使用子部件定义微观样式8.1. 相对定 ...

  6. MD基本语法介绍

    Markdown基本语法介绍 前言 文本编辑器一般用的有富文本编辑器(也就是Word)和md了,但是wold太过于花里胡哨很多功能都用不上,所以就选择md了,简单实用,一对于我来说一般就用标题和列表就 ...

  7. Markdown 语法介绍

    Markdown 语法介绍 from:https://coding.net/help/doc/project/markdown.html 文章内容 1 Markdown 语法介绍 1.1 标题 1.2 ...

  8. css基本概念与css核心语法介绍

    css基本概念 css是什么?不需要了解太多文字类介绍,记住css是层叠样式表,HTML是页面结构,css负责页面样式,javascrt负责静态页面的交互.CSS 能够对网页中元素位置的排版进行像素级 ...

  9. c基本语法介绍

    c语言基本语法介绍 1.把常量定义为大写字母形式,是一个很好的编程实践.

随机推荐

  1. POJ 1329 Circle Through Three Points(三角形外接圆)

    题目链接:http://poj.org/problem?id=1329 #include<cstdio> #include<cmath> #include<algorit ...

  2. hql 语法与详细解释

    HQL查询: Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hi ...

  3. 10-MySQL-Ubuntu-数据表中数据的查询(三)

    数据的查询(select) (1)查询整个表的数据: select  * from 表名; (2)查询给定条件的数据: select  * from 表名 where 条件; (3)查询表中某些字段: ...

  4. 2019ICPC南京网络赛A The beautiful values of the palace

    题意:蛇形填数超大版本,需要求出一些给定坐标的值的数位和,然后q次询问,一个矩形区域内值的和是多少 解题思路:二维偏序前缀和的经典题 二维偏序:求(x,y)左下角点的个数,思路是对x,y升序排序,用树 ...

  5. (转)Java中Image的水平翻转、缩放与自由旋转操作

    来自:http://cping1982.blog.51cto.com/601635/130066/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责 ...

  6. Vue之数据排序加签

    这篇随笔小编给大家带来的是数据排序加签: 所谓数据加签,就是把数据进行加密再传给后端,这样保证数据的秘密性.不容易被修改和获取:排序就是根据公司要求对字段进行排序,有些公司会把字段根据a-z排序,有些 ...

  7. 前端 Vue

    0.渐进式 JavaScript 框架 通过对框架的了解与运用程度,来决定其在整个项目中的应用范围,最终可以独立以框架方式完成整个web前端项目 一.Vue介绍 1.什么是Vue 可以独立完成前后端分 ...

  8. <%#Eval() %>的常用方法

    <%# %>用于数据绑定,通常是用在数据源控件里,比如GridView,Repeater等. 1.绑定Repeater 基础用法 <%# Eval("DriverName& ...

  9. laravel 关掉debug

    修改.env文件 APP_DEBUG=false 然后把Laravel服务重启一下

  10. 安装memcached报错:If it's already installed, specify its path using --with-libevent=/dir/

    一.安装memcached,执行./configure --prefix=/usr/local/memcached时候报错: 问题:If it's already installed, specify ...