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

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

规则结构

image

规则中的条件

image
DRL中的when部分就是规则的条件(通常又叫做规则的左手边,即:Left Hand Side(LHS)
只有满足了所有的条件,才回去执行then部分,如果when部分为空,就是没有条件,那么就默认为true,下面是一个空条件的例子:

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,就是同时满足所有条件

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等于50

Person( age == 50 )

约束是一个会返回true或false的表达式,和java很像,但是有所增强,可以直接通过属性名访问属性

Person( age == 50 )

// 这两者是一样的

Person( getAge() == 50 )

如果约束的值类型和属性的类型不一致,那么drools内部会自动做强制类型转换,如果转不了就会报错,比如:

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

多个约束:

// 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 )

也可以使用&&和||,但是不可以和","混用

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

// 应该这样用:
Person( ( age > 50 && weight > 80 ) || height > 2 )
在模式和约束中绑定变量

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

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: Error code

  • 2nd Block: Line and column in the DRL source where the error occurred

  • 3rd Block: Description of the problem

  • 4th Block: Component in the DRL source (rule, function, query) where the error occurred

  • 5th Block: Pattern in the DRL source where the error occurred (if applicable)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值