天天看点

drools_07_macro_functions

delete()和retract() 宏函数

delete() 用于在rule RHS中将对象从工作内存中删除, retract()函数有同样的作用, 不过已经被标记为废弃状态.

insert() 宏函数

insert() 用于在rule RHS中增加新的fact对象, 新的fact对象会自动完成模式匹配, 所以需要避免循环触发问题.

update()和 modify() 宏函数

update和modify 用于在rule RHS中修改fact对象,并期望对该fact对象重新模式匹配, 如果不期望重新模式匹配, 不需要调用这两个宏函数, 调用这两个函数需要额外注意不要引起循环rule触发.

循环触发问题

  • 在update()/modify()所在的rule, 如果更新的属性同时用在了LHS条件中, 那么drools认为需要触发该规则, 这时很容易发生循环触发问题, 需要格外注意, 可以为rule增加 no-loop 属性来避免.
  • 在update()/modify()所在的rule, 如果修改的属性没用在了LHS条件中, drools会智能地判断出没有必要触发该规则, 对于该规则来讲是没有循环重复问题. 但如果先触发了另一个规则, 在那个规则中又对原规则的LHS条件属性做了修改, 这样还会出现循环触发问题, 这时即使加了no-loop 属性也不管用.
// 修改了amount属性, 但是LHS用的是originalPrice属性, 所以对于本规则不会循环触发
rule "not_worry_loop"
   when
       $order:Order(originalPrice>0)
   then
      $order.setAmount(100);
      update($order) ;
      System.out.println("rule fired") ;
end      
// 修改了amount属性, LHS也使用了amount属性, 所以会循环触发
rule "always_loop"
   when
       $order:Order(amount>0)
   then
      $order.setAmount(100);
      update($order) ;
      System.out.println("rule fired") ;
end      

update() 和 modify()区别

  • 推荐使用 modify() 而不是 update()

    官方的解释是: After a fact has changed, you must call ​​

    ​update​

    ​​ before changing another fact that might be affected by the updated values. To avoid this added step, use the ​

    ​modify​

    ​ method instead.
  • 语法比较

    update()语法简单, modify()语法比较奇怪, 要将修改的属性包在{ } 中, 见下面的示例.

rule "not_worry_loop2"
   when
       $order:Order(originalPrice>0)
   then
      modify($order) {
        setAmount(100);
      }
      System.out.println("rule fired") ;
end      

继续阅读