drools规则语言指南(五)规则条件和行为

DRL中的规则条件(WHEN,LHS)

规则结构

image

规则中的条件

image
DRL中的when部分就是规则的条件(一般又叫作规则的左手边,即:Left Hand Side(LHS)
只有知足了全部的条件,才回去执行then部分,若是when部分为空,就是没有条件,那么就默认为true,下面是一个空条件的例子:html

rule "Always insert applicant"
  when
    // Empty
  then   // Actions to be executed once
    insert( new Applicant() );
end

// 规则在引擎内部会变成以下这样:

rule "Always insert applicant"
  when
    eval( true )
  then
    insert( new Applicant() );
end

若是条件之间没有连词的话(如:and,or,not),默认的就是and,就是同时知足全部条件java

rule "Underage"
  when
    application : LoanApplication()
    Applicant( age < 21 )
  then
    // Actions
end

// 在规则引擎内部是下面这样,加上个and:

rule "Underage"
  when
    application : LoanApplication()
    and Applicant( age < 21 )
  then
    // Actions
end

模式和约束

在规则的条件中定义模式并由规则去匹配,一个模式能够匹配每个被插入到working memory中的fact,同时模式也能够增长约束去限制哪些fact会被匹配上
image
举个没有约束的例子,下面定的这个模式,能够匹配全部插入到WM中的Person对象。正则表达式

Person()

这个类型不须要是一个真是的class,能够是父类甚至是接口,好比下面这个例子就会匹配WM中全部的对象算法

Object() // Matches all objects in the working memory

增长了约束的模式,限制了age等于50express

Person( age == 50 )

约束是一个会返回true或false的表达式,和java很像,可是有所加强,能够直接经过属性名访问属性segmentfault

Person( age == 50 )

// 这二者是同样的

Person( getAge() == 50 )

若是约束的值类型和属性的类型不一致,那么drools内部会自动作强制类型转换,若是转不了就会报错,好比:app

Person( age == "10" ) // "10" 强制转为 10

多个约束:dom

// Person is at least 50 years old and weighs at least 80 kilograms:
Person( age > 50, weight > 80 )

// Person is at least 50 years old, weighs at least 80 kilograms, and is taller than 2 meters:
Person( age > 50, weight > 80, height > 2 )

也可使用&&和||,可是不能够和","混用ide

// 不能用:
Person( ( age > 50, weight > 80 ) || height > 2 )

// 应该这样用:
Person( ( age > 50 && weight > 80 ) || height > 2 )

在模式和约束中绑定变量

使用$变量名这种形式来绑定变量:spa

rule "simple rule"
when
    $p : Person()
then
    System.out.println( "Person " + $p );
end

注意:

// 不能这样用:
Person( $age : age * 2 < 100 )

// 要这样用:
Person( age * 2 < 100, $age : age )

嵌套约束和内联强制转换

嵌套约束的使用:

Person( name == "mark", address.city == "london", address.country == "uk" )
//或者写成:
Person( name == "mark", address.( city == "london", country == "uk") )

内联强制转换:

// Inline casting with subtype name:
Person( name == "mark", address#LongAddress.country == "uk" )

// Inline casting with fully qualified class name:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )

// Multiple inline casts:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )

使用instanceof进行类型判断

Person( name == "mark", address instanceof LongAddress, address.country == "uk" )

日期约束

默认的日期格式是dd-mm-yyyy,你也能够自定义格式经过系统属性drools.dateformat="dd-mm-yyyy hh:mm"

Person( bornBefore < "27-Oct-2009" )

DRL特有的操做符

DRL支持标准的java语法,可是有些操做符是DRL所独有的,好比:.(),#,经过前者去分组获取属性值,经过后者强制类型转换成子类型

// Ungrouped property accessors:
Person( name == "mark", address.city == "london", address.country == "uk" )

// Grouped property accessors:
Person( name == "mark", address.( city == "london", country == "uk") )
// Inline casting with subtype name:
Person( name == "mark", address#LongAddress.country == "uk" )

// Inline casting with fully qualified class name:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )

// Multiple inline casts:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )

!. 操做符至关于!=null

Person( $streetName : address!.street )

// This is internally rewritten in the following way:

Person( address != null, $streetName : address.street )

[ ] 获取list或map的值

// The following format is the same as `childList(0).getAge() == 18`:
Person(childList[0].age == 18)

// The following format is the same as `credentialMap.get("jdoe").isValid()`:
Person(credentialMap["jdoe"].valid)

matches , not matches 正则匹配,与java中使用正则表达式相同

Person( country matches "(USA)?\\S*UK" )

Person( country not matches "(USA)?\\S*UK" )

contains , not contains 判断值是否在Array或Collection中

// Collection with a specified field:
FamilyTree( countries contains "UK" )

FamilyTree( countries not contains "UK" )


// Collection with a variable:
FamilyTree( countries contains $var )

FamilyTree( countries not contains $var )

一样能够用于字符串的包含,至关于String.contains(),!String.contains()

// Sting literal with a specified field:
Person( fullName contains "Jr" )

Person( fullName not contains "Jr" )


// String literal with a variable:
Person( fullName contains $var )

Person( fullName not contains $var )

memberOf , not memberOf 判断字段值是否在Array或Collection中,它们必须是 变量

FamilyTree( person memberOf $europeanDescendants )

FamilyTree( person not memberOf $europeanDescendants )

soundslike 英语发音类似,使用 Soundex algorithm算法判断(nubility)

// Match firstName "Jon" or "John":
Person( firstName soundslike "John" )

str 判断一个字符串是否已指定值开头、结尾、以及长度是多少

// Verify what the String starts with:
Message( routingValue str[startsWith] "R1" )

// Verify what the String ends with:
Message( routingValue str[endsWith] "R2" )

// Verify the length of the String:
Message( routingValue str[length] 17 )

in , not in

Person( $color : favoriteColor )
Color( type in ( "red", "blue", $color ) )

Person( $color : favoriteColor )
Color( type notin ( "red", "blue", $color ) )

还有不少其余的操做符合关键字能够参考这个

DRL中的规则行为(THEN)

DRL中的then部分就是规则触发后的行为(规则的右手边Right Hand Side (RHS) ),基本上能够概况为向working memory中 insert、delete、或modify数据。

rule "Underage"
  when
    application : LoanApplication()
    Applicant( age < 21 )
  then
    application.setApproved( false );
    application.setExplanation( "Underage" );
end
DRL中支持的行为

set 设置字段值,和java相同

set<field> ( <value> )

例:

$application.setApproved ( false );
$application.setExplanation( "has been bankrupt" );

modify 修改对象并告知engine

modify ( <fact-expression> ) {
    <expression>,
    <expression>,
    ...
}

例:

modify( LoanApplication ) {
        setAmount( 100 ),
        setApproved ( true )
}

update 更新对象并告知engine

update ( <object, <handle> )  // Informs the Drools engine that an object has changed

update ( <object> )  // Causes `KieSession` to search for a fact handle of the object

例:

LoanApplication.setAmount( 100 );
update( LoanApplication );

能够看出,咱们能够用modify来代替,可是update提供了额外的监听器,来监听属性值的变化,属性监听器

insert 插入一个新的fact

//用法:
insert( new <object> );
//例:
insert( new Applicant() );

insertLogical 逻辑插入一个新的fact,drools engine负责这个fact的建立和回收,当建立这个fact的条件为false时,这个fact就会被engine自动回收掉

//用法:
insertLogical( new <object> );
//例:
insertLogical( new Applicant() );

delete 删除一个对象,retract也能够,可是建议使用delete

//用法
delete( <object> );
//例:
delete( Applicant );

注释

和java中的注释相同

rule "Underage"
  // This is a single-line comment.
  when
    $application : LoanApplication()  // This is an in-line comment.
    Applicant( age < 21 )
  then
    /* This is a multi-line comment
    in the rule actions. */
    $application.setApproved( false );
    $application.setExplanation( "Underage" );
end

DRL中的错误信息

若是规则有问题,会按照以下格式输出
image

  • 1st Block: 错误码
  • 2nd Block: 源码中出现错误的位置在多少行
  • 3rd Block: 问题描述
  • 4th Block: 错误在源码的哪一个部分
  • 5th Block: 源码的哪一个模式出错误了
相关文章
相关标签/搜索