这篇文章主要介绍“drools中then部分怎么写”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“drools中then部分怎么写”文章能帮助大家解决问题。1、背景此处介绍一下drools中then部
这篇文章主要介绍“drools中then部分怎么写”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“drools中then部分怎么写”文章能帮助大家解决问题。
此处介绍一下drools
中then
部分的写法,以及一些内置的方法,比如insert/delete/modify
等等。同时也介绍一下rule
的继承,和在when
中实现if else if
等操作。
drools提供了一些内置的方法,这些方法会修改drools的工作内存
中Fact
对象的值。从而会导致重新进行模式匹配。
insert
是向工作内存中插入对象,同时会导致重新进行规则的模式匹配。同时当规则不满足时,不会自动删除。
当发生火灾Fire
时,向工作内存中插入一个Alarm
对象,告警发生后,删除工作内存中的Fire
对象,然后检测Alarm
对象是否还存在。
package rulesimport com.huan.drools.insertmethod.Fireimport com.huan.drools.insertmethod.Alarmrule "insert_发生火灾时,往工作内存中插入告警对象" when $fire: Fire() then System.out.println("1、发生火灾时,往工作内存中插入告警对象"); insert(new Alarm($fire));endrule "insert_当规则内存中存在告警对象,进行告警,然后删除火灾对象" when $fire: Fire() $alarm: Alarm( fire == $fire ) then System.out.println("2、进行告警,然后删除对应的火灾对象");endrule "insert_检测告警对象是否还是存在-01" when Alarm() then System.out.println("3、insert 插入的告警对象还存在"); // 删除工作内存中的Fire对象 delete($fire);endrule "insert_检测告警对象不存在" when not Alarm() then System.out.println("3、insert 插入的告警对象不存在");end
此处使用的是 insert
进行插入
// 将火灾对象插入到工作内存中kieSession.insert(new Fire());// 只触发规则名称以 insert_ 开头的规则kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insert_"));
发生火灾时,往工作内存中插入告警对象
2、进行告警,然后删除对应的火灾对象
3、insert 插入的告警对象还存在
insert可以向工作内存中插入Fact对象。
insert方法调用后,会导致模式的重新匹配,导致之前不会执行的规则,重新执行。
insert方法插入到工作内存的对象,在规则不成立时,不会自动删除,需要手动删除,注意和insertLogical的区别
insert
是向工作内存中插入对象,同时会导致重新进行规则的模式匹配。同时当规则不满足时,会自动删除。
当发生火灾Fire
时,向工作内存中插入一个Alarm
对象,告警发生后,删除工作内存中的Fire
对象,然后检测Alarm
对象是否还存在。
package rulesimport com.huan.drools.Fireimport com.huan.drools.Alarmrule "insertLogical_发生火灾时,往工作内存中插入告警对象" when $fire: Fire() then System.out.println("1、发生火灾时,往工作内存中插入告警对象"); insertLogical(new Alarm($fire));endrule "insertLogical_当规则内存中存在告警对象,进行告警,然后删除火灾对象" when $fire: Fire() $alarm: Alarm( fire == $fire ) then System.out.println("2、进行告警,然后删除对应的火灾对象"); delete($fire);endrule "insertLogical_检测告警对象是否还是存在-01" when Alarm() then System.out.println("3、insertLogical 插入的告警对象还存在");endrule "insertLogical_检测告警对象不存在" when not Alarm() then System.out.println("3、insertLogical 插入的告警对象不存在");end
此处使用的是insertLogical
插入
kieSession.insert(new Fire());kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insertLogical_"));
发生火灾时,往工作内存中插入告警对象
2、进行告警,然后删除对应的火灾对象
3、insertLogical 插入的告警对象不存在
insertLogical可以向工作内存中插入Fact对象。
insertLogical方法调用后,会导致模式的重新匹配,导致之前不会执行的规则,重新执行。
insertLogical方法插入到工作内存的对象,在规则不成立时,会自动删除注意和insert的区别
update:
使用它来指定要更新的字段和整个相关Fact,并将更改通知 Drools 引擎。 Fact发生更改后,您必须在更改可能受更新值影响的另一个事实之前调用 update。 为避免此添加步骤,请改用 modify 方法。
规则一: 当工作内存中存在火灾对象Fire
,并且名字name为空时触发规则,同时在设置火灾的名字为大火灾
。
规则二: 当火灾存在名字时,输出火灾名字
package rulesimport com.huan.drools.Fireimport com.huan.drools.Alarmrule "update_当存在火灾对象时,设置一个火灾的名字" when $fire: Fire(name == null) then System.out.println("1、设置火灾名字"); $fire.setName("大火灾"); update($fire)endrule "update_当火灾对象存在名字时触发" when $fire: Fire(name != null) then System.out.println("2、火灾对象的名字为: " + $fire.getName());end
kieSession.insert(new Fire());kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("update_"));
设置火灾名字
2、火灾对象的名字为: 大火灾
update
会导致模式的重新匹配。
update
会修改工作对象内存中的值。
modify:
使用它来指定要为Fact对象修改的字段并将更改通知 Drools 引擎。 此方法提供了一种结构化的事实更新方法。 它将更新操作与 setter 调用相结合以更改对象字段。
规则一: 当工作内存中存在火灾对象Fire
,并且名字name为空时触发规则,同时在设置火灾的名字为大火灾
。
规则二: 当火灾存在名字时,输出火灾名字
package rulesimport com.huan.drools.Fireimport com.huan.drools.Alarmrule "modify_当存在火灾对象时,设置一个火灾的名字" when $fire: Fire(name == null) then System.out.println("1、设置火灾名字"); modify($fire){ setName("大火灾") }endrule "modify_当火灾对象存在名字时触发" when $fire: Fire(name != null) then System.out.println("2、火灾对象的名字为: " + $fire.getName());end
kieSession.insert(new Fire());kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("modify_"));
设置火灾名字
火灾对象的名字为: 大火灾
modify
会导致模式的重新匹配。
modify
会修改工作对象内存中的值。一般情况下使用modify
,不要使用update
。
用法:delete(<object>)
retract
也是和delete
一样的效果,但是推荐使用delete
。
package rulesrule "drools_变量的使用" wh eval(true) then System.out.println("Match激活的当前触发规则: " + drools.getMatch()); System.out.println("当前触发规则的名字: " + drools.getRule().getName()); // System.out.println("终止规则执行fireUntilHalt(): " + drools.getKieRuntime().halt()); // System.out.println("激活AgendaGroup组: " + drools.getKieRuntime().getAgenda().getAgendaGroup( "CleanUp" ).setFocus()); System.out.println("获取所有全局变量: " + drools.getKieRuntime().getGlobals()); // System.out.println("设置全局变量:" + drools.getKieRuntime().setGlobal("username","huan"); ); // System.out.println("获取查询结果:" + drools.getKieRuntime().getQueryResults());end
规则一: 如果用户(customer
)的年龄(age
)大于60岁,则打0.9
折。
规则二: 在规则一的基础上,如果用户有车(car
),则可以免费停车(freeParking
)。
package rulesimport com.huan.drools.Customerimport com.huan.drools.Carrule "rule_extends_规则一" when $c: Customer(age > 60) then modify($c){ setDiscount(0.9) } System.out.println("触发规则一:用户年龄>60岁,打0.9折");end// 规则二继承规则一的条件rule "rule_extends_规则二" extends "rule_extends_规则一" when $car: Car() then modify($car){ setFreeParking(true) } System.out.println("触发规则二:用户有车,免费停车");end
此处rule_extends_规则二
继承了rule_extends_规则一
,所以规则一的条件也继承了。
Car car = new Car();Customer customer = new Customer();customer.setAge(65);kieSession.insert(customer);kieSession.insert(car);kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_extends_"));
客户有车,并且年龄是65岁,满足上方的规则一和规则二
触发规则一:用户年龄>60岁,打0.9折
触发规则二:用户有车,免费停车
可以看到在rule
上使用extends
关键字,可以实现规则的继承。
只要用户大于60岁,直接打0.9折,如果还有车,则可以免费停车。
package rulesimport com.huan.drools.Customerimport com.huan.drools.Carrule "命名结果_rule" when $c: Customer(age > 60) do[giveDiscount] // 当上方的条件成立时执行 then [giveDiscount] $car: Car() // 此条件成立时,执行默认的 then then modify($car){ setFreeParking(true) }; System.out.println("用户有车,免费停车"); then [giveDiscount] modify($c){ setDiscount(0.9) }; System.out.println("用户年龄>60岁,打0.9折");end
解释:
见上方的规则文件里的注视
Car car = new Car();Customer customer = new Customer();customer.setAge(65);kieSession.insert(customer);kieSession.insert(car);kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("命名结果_"));
用户年龄>60岁,打0.9折
用户有车,免费停车
也实现了需求
通过when
中使用 do[名字]
然后 then
then 名字
也可以实现。
完成类似 if else if else
效果。见下方的各种执行结果。
rule "if else-if" when $customer: Customer(age > 60) // 规则内存中存在Customer对象,并且age>60 if($customer.getLevel() == 1) do[level1] // 用户的级别是1,执行then[level1],然后继续执行下方的条件 else if ($customer.getLevel() == 2) break[level2] // 用户的级别是2,执行then[level2],不在执行下方的条件 else do[levelOther] // 其他的level级别,执行then[levelOther],然后在执行下方的条件 Car() then System.out.println("我执行了"); then[level1] System.out.println("level1"); then[level2] System.out.println("level2"); then[levelOther] System.out.println("levelOther");end
Customer
的age
小于60
。输出:
没有输出。
2、Customer
的age
大于60
并且level=1
,没有Car
。输出:
level1
3、Customer
的age
大于60
并且level=1
,有Car
。输出:
level1 我执行了
4、Customer
的age
大于60
并且level=2
,没有Car
。输出:
level2
5、Customer
的age
大于60
并且level=2
,有Car
。输出:
level2
6、Customer
的age
大于60
并且level=3
,没有Car
。输出:
levelOther
7、Customer
的age
大于60
并且level=3
,有Car
。输出:
levelOther 我执行了
do
:执行完之后,还会继续判断后面的执行条件。 (即还会执行后面的Car判断,根据是否有Car获取不同的结果
)break
:执行完之后,不会在判断后面的执行条件。(即忽略了后面的Car判断,rule执行完了
)
关于“drools中then部分怎么写”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。
--结束END--
本文标题: drools中then部分怎么写
本文链接: https://lsjlt.com/news/330194.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0