delete()和retract() 宏函数
delete() 用于在rule RHS中将对象从工作内存中删除, retract()函数有同样的作用, 不过已经被标记为废弃状态.
insert() 宏函数
insert() 用于在rule RHS中增加新的fact对象, 新的fact对象会自动完成模式匹配, 所以需要避免循环触发问题.
update()和 modify() 宏函数
update和modify 用于在rule RHS中修改fact对象,并期望对该fact对象重新模式匹配, 如果不期望重新模式匹配, 不需要调用这两个宏函数, 调用这两个函数需要额外注意不要引起循环rule触发.
循环触发问题
当然, drools 也有机制尽量避免无谓的重复模式匹配, 具体说明:
- 在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