Drools规则引擎使用

Drools语法

规则文件

规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件
在这里插入图片描述

package

对一个规则文件而言,package是必须定义的,必须放在规则文件第一行,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分
如:

package com.sankuai.meituan.waimai.drools.demo

import

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

import com.drools.demo.point.PointDomain;

rule

定义一个具体规则。rule “ruleName”。一个规则可以包含三个部分:

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

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

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

rule部分
rule “ruleName”
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:lock-on-active true 通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版

date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”

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

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

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

在这里插入图片描述

rule attributes
条件部分- LHS

when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列
如:当前规则只有在这三个条件都匹配的时候才会执行RHS部分
when
      eval(true)
      $customer:Customer()
      $message:Message(status==0)
eval(true):是一个默认的api,true 无条件执行,类似于 while(true)
操作符:>、>=、<、<=、==、!=、contains、not contains、memberOf、not memberOf、matches、not matches

操作符

    contains: 对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值
    Person( fullName not contains "Jr" )
    not contains:与contains相反。
    memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象
    CheeseCounter( cheese memberOf $matureCheeses )
    not memberOf:与memberOf正好相反
    matches:正则表达式匹配
    Cheese( type matches "(Buffalo)?\\S*Mozarella" )
    注意: 就像在Java中,写为字符串的正则表达式需要转义“\”
    not matches:与matches正好相反

结果部分- RHS

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

then:
then
     System.out.println("OK"); //会在控制台打印出ok
end
insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定
update:更新
modify:修改,与update语法不同,结果都是更新操作
retract:删除
rule "Rule 03" 
      when 
          $number : Number( ) 
          not Number( intValue < $number.intValue ) 
      then 
          System.out.println("Number found with value: " + $number.intValue() ); 
          retract( $number );
end

Drools方法定义

function

function String hello(String name) {
return “Hello “+name+”!”;
}

Drools声明类型

declare:声明类型

    声明Class、Enum etc类型
    声明元数据

声明类类型

declare  Address 
    number : int 
    streetName : String 
    city : String
end

声明枚举类型

declare enum DaysOfWeek
    SUN("Sunday"),MON("Monday"),TUE("Tuesday"),WED("Wednesday"),THU("Thursday"),FRI("Friday"),SAT("Saturday"); 
    fullName : String
end

Drools关键词

关键词描述详情
lock-on-active
date-effective
date-expires
no-loop
auto-focus
activation-group
agenda-group
ruleflow-group
entry-point
duration
package
import
dialect
salience
enabled
attributes
rule
extend
when
then
when
template
query
declare
function
eval
not
in
or
and
exists
forall
exists
accumulate
collect
from
action
reverse
result
end
over
init

引用

官方文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值