【java】drools入门之LHS和RHS语法

很自然地,笔者将分成两部分进行讲解。

1. LHS语法

LHS 是规则条件部分的统称,由 0 个或多个条件元素组成。前面我们已经提到,如果没有条件元素那么默认就是true。

1.1 Pattern 绑定

当匹配到对象时,可以将 FACT 对象绑定到指定的变量上。这里的用法类似于 java 的变量定义。绑定之后,在后面就可以直接使用此变量。

rule ...
    when
        $p : Person()
    then
        System.out.println( "Person " + $p );
    end
// 2 person 的 age 属性值相同
Person( $firstAge : age ) // 绑定
Person( age == $firstAge ) // 约束表达式

 其中,前缀$只是一个约定标识,有助于在复杂的规则中轻松区分变量和字段,但并不强制要求必须添加此前缀。

1.2 访问 JavaBean 中的属性

任何一个 JavaBean 中的属性都可以访问,不过对应的属性要提供 getter 方法或isProperty 方法。比如:

Person( age == 50 )
// 与上面拥有同样的效果
Person( getAge() == 50 )

1.3 内部类分组访问

通常情况,我们访问一个内部类的多个属性时会有如下的写法: 

Person( name == "mark", address.city == "london", address.country == "uk" )

1.4 Java 表达式

在 pattern 的约束条件中,可以任何返回结果为布尔类型的 java 表达式。当然,java 表达式也可以和增强的表达式进行结合使用,比如属性访问。可以通过使用括号来更改计算优先级,如在任一逻辑或数学表达式中。 

Person( age > 100 && ( age % 10 == 0 ) )

也可以直接使用 java 提供的工具方法来进行操作计算:

Person( Math.round( weight / ( height * height ) ) < 25.0 )

在使用的过程中需要注意,在 LHS 中执行的方法只能是只读的,不能在执行方法过程中改变 FACT 对象的值,否则会影响规则的正确执行。

1.5 matches 正则表达式

可使用 Java 的正则表达式进行字符串的匹配,通常情况下使用正则表达式字符串进行匹配,但也支持变量值为正确的表达式的方式。此操作符仅适用于字符串属性。如果属性值为 null,匹配的结果始终为 false。

Cheese( type matches "(Buffalo)?\\S*Mozzarella" )

not matches 方法与 matches 相同,唯一不同的是返回的结果与之相反。

Cheese( type not matches "(Buffalo)?\\S*Mozzarella" )

1.6 contains 和 memberOf 操作符

contains 判断一个集合属性或元素是否包含指定字符串或变量值。仅适用于集合属性。也可以用于替代 String.contains()来检查约束条件。not contains 用法与之相同,结果取反。

CheeseCounter( cheeses contains "stilton" ) // 包含字符串
CheeseCounter( cheeses contains $var ) // 包含变量
Cheese( name contains "tilto" )
Person( fullName contains "Jr" )
String( this contains "foo" )

memberOf 用来检查属性值是否为集合,此集合的表示必须为变量。not memberOf 使用方法相同,结果取反。

CheeseCounter( cheese memberOf $matureCheeses )

1.7 字符串操作符 str 和 in

str 操作用来比较一个字符串是否以指定字符串开头或结尾,有可以用于比较字符串的长度。

Message( routingValue str[startsWith] "R1" )
Message( routingValue str[endsWith] "R2" )
Message( routingValue str[length] 17 )

in 和 notin 用来匹配一组数据中是否含一个或多个匹配的字符串,使用的方法与数据库中 in 的使用方法相似。待匹配的数据可以是字符串、变量。

Person( $cheese : favouriteCheese )
Cheese( type in ( "stilton", "cheddar", $cheese ) ) 

2. THS语法

RHS 是满足 LHS 条件之后进行后续处理部分的统称,该部分包含要执行的操作的列表信息。RHS 主要用于处理结果,因此不建议在此部分再进行业务判断。如果必须要业务判断需要考虑规则设计的合理性,是否能将判断部分放置于 LHS,那里才是判断条件应该在的地方。

同时,应当保持 RHS 的精简和可读性。如果在使用的过程中发现需要在 RHS 中使用 AND 或 OR 来进行操作,那么应该考虑将
一根规则拆分成多个规则。RHS 的主要功能是对 working memory 中的数据进行 insert、update、delete 或 modify 操作,Drools 提供了相应的内置方法来帮助实现这些功能。下面分别介绍:

2.1  insert 函数

insert 的作用与在 Java 类当中调用 KieSession 的 insert 方法效果一样,都是将 Fact 对象插入到当前的 Working Memory 当中,基本用法格式如下:

insert(newSomething());

调用 insert 之后,规则会进行重新匹配,如果没有设置 no-loop 为 true 或 lock-on-active 为 true 的规则,如果条件满足则会重新执行。update、modify、delete 都具有同样的特性,因此在使用时需特别谨慎,防止出现死循环。

规则文件 insert.drl

package com.rules

import com.secbro.drools.model.Product

rule "insert-check"
    salience 1

    when
        $p : Product(type == GOLD);
    then
        System.out.println("insert-check:insert Product success and it's type is " + $p.getType());
    end

rule "insert-action"
    salience 2

    when
    then
        System.out.println("insert-action : To
        insert the Product");
        Product p = new Product();
        p.setType(Product.GOLD);
    insert(p);
end

打印日志: 

insert-action : To insert the Product
insert-check:insert Product success and it's type is GOLD
Fire 2 rules!
根据优先级首先执行 insert 操作的规则,然后执行结果检测。

2.2 update 函数

update 函数可对 Working Memory 中的 FACT 对象进行更新操作,与 StatefulSession 中的 update 的作用基本相同。查看 KnowledgeHelper 接口中的 update 方法可以发现,update函数有多种参数组合的使用方法。在实际使用中更多的会传入 FACT 对象来进行更新操作。

2.3 delete 函数

将 Working Memory 中的 FACT 对象删除,与 kession 中的 retract/delete 方法效果一样。同时 delete 函数和 retract 效果也相同,但后者已经被废弃。

2.4  modify 函数

modify 是基于结构化的更新操作,它将更新操作与设置属性相结合,用来更改 FACT 对象的属性。语法格式如下:

modify ( <fact-expression> ) {
    <expression> [ , <expression> ]*
}

其中<fact-expression>必须是 FACT 对象的引用,expression 中的属性必须提供 setter 方法。在调用 setter 方法时,不必再写 FACT 对象的引用,编译器会自动添加。

rule "modify stilton"

    when
        $stilton : Cheese(type == "stilton")
    then
        modify( $stilton ){
            setPrice( 20 ),
            setAge( "overripe" )
        }
end

更多内容可以访问大佬的博客:http://blog.csdn.net/wo541075754

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值