当前位置: 首页 > 后端技术 > Java

后面部分的写法流口水

时间:2023-04-01 21:26:20 Java

1.背景这里介绍一下drools中then部分的写法,以及一些内置的方法,比如insert/delete/modify等。同时还引入了规则的继承,实现了ifelseifinwhen等操作。2、支持的方法drools提供了一些内置的方法,可以修改drools工作内存中Fact对象的值。这将导致重复模式匹配。2.1insertInsertinganobjectintotheworkingmemoryInsert是将一个对象插入到工作内存中,同时会导致正则模式匹配再次进行。同时,当不满足规则时,也不会自动删除。2.1.1要求当火灾发生时,将一个报警对象插入到工作内存中。告警发生后,删除工作内存中的Fire对象,然后查看Alarm对象是否还存在。2.1.2drl文件写入包rulesimportcom.huan.drools.insertmethod.Fireimportcom.huan.drools.insertmethod.Alarmrule"insert_Whenafireoccurs,insertanalarmobjectintotheworkingmemory"when$fire:Fire()thenSystem.out.println("1.发生火灾时,向工作内存中插入一个报警对象");插入(新警报($fire));endrule"插入_当规则内存中有报警对象时,发出报警,然后删除fire对象"when$fire:Fire()$alarm:Alarm(fire==$fire)thenSystem.out.println("2.报警,然后删除对应的火灾对象");endrule"insert_检测报警对象是否仍然存在-01"whenAlarm()thenSystem.out.println("3.insert插入的报警对象仍然存在");//删除工作内存中的Fire对象delete($fire);endrule"insert_detectionalarmTheobjectdoesnotexist"whennotAlarm()thenSystem.out.println("3.insert插入的报警对象不存在");end这里insert用于insert2.1.3部分java代码编写//将fire对象Insert到工作内存中kieSession.insert(newFire());//只触发规则名以insert_kieSession开头的规则.fireAllRules(newRuleNameStartsWithAgendaFilter("insert_"));2.1.4运行结果1.发生火灾时,将报警对象插入工作内存2.报警,然后删除对应的火灾对象3.insert插入的报警对象仍然存在2.1.5结论insertcanFact对象insert方法插入工作内存后,会重新匹配pattern,重新执行之前没有执行的规则。通过insert方法插入工作内存的对象在规则不成立时不会自动删除,需要手动删除。注意与insertLogical2.2的区别insertLogical将一个对象插入到工作内存中。规则的模式匹配。同时,当不满足规则时,会自动删除。2.2.1要求当火灾发生时,将一个报警对象插入到工作内存中。告警发生后,删除工作内存中的Fire对象,然后查看Alarm对象是否还存在。2.2.2drl文件编写包rulesimportcom.huan.drools.Fireimportcom.huan.drools.Alarmrule"insertLogical_当发生火灾时,将一个报警对象插入到工作内存中"when$fire:Fire()thenSystem.out。println("1.发生火灾时,向工作内存中插入一个报警对象");插入逻辑(新警报($fire));endrule"insertLogical_当规则内存中有报警对象时,发出报警,然后删除fire对象"when$fire:Fire()$alarm:Alarm(fire==$fire)thenSystem.out。println("2.进行报警,然后删除对应的火灾对象");删除($火);endrule"insertLogical_检测报警对象是否仍然存在-01"whenAlarm()thenSystem.out.println("3.insertLogical插入的报警对象仍然存在");endrule"insertLogical_检测报警对象不存在"whennotAlarm()thenSystem.out.println("3.insertLogical插入的报警对象不存在");到此结束使用insertLogical插入2.2.3部分java代码编写kieSession.insert(newFire());kieSession.fireAllRules(newRuleNameStartsWithAgendaFilter("insertLogical_"));2.2.4运行结果1.发生火灾时,插入报警对象2.报警,然后删除对应的火灾对象3.insertLogical插入的报警对象不存在。2.2.5结论insertLogical可以将一个Fact对象插入到工作内存中。将要执行的规则,重新执行。insertLogical方法将对象插入到工作内存中。当规则不成立时,会自动删除。请注意与insert2.3的区别。update更新工作内存中的对象update:用它来指定要更新的字段和整个相关的Fact,并通知Drools引擎发生变化。事实更改后,您必须在更改可能受更新值影响的另一个事实之前调用更新。要避免这个添加的步骤,请改用修改方法。2.3.1需求规则1:当工作内存中有火对象Fire,且名称name为空时,触发规则,将火的名称设置为大火。规则二:当火的名字存在时,输出火的名字2.3.2编写drl文件包rulesimportcom.huan.drools.Fireimportcom.huan.drools.Alarmrule"update_当有火对象时,设置火灾的名称"when$fire:Fire(name==null)thenSystem.out.println("1,setfirename");$fire.setName("大火");update($fire)endrule"update_whenthefireobjectexists当name为"时触发when$fire:Fire(name!=null)thenSystem.out.println("2.fire对象的名称为:"+$fire.getName());end2.3.3一些java文件写的是kieSession。插入(新Fire());kieSession.fireAllRules(新RuleNameStartsWithAgendaFilter(“update_”));2.3.4运行结果1.设置火种名称2.火种名称为:大火2.3.4结论更新会??导致模式重新匹配。update修改工作对象内存中的值。2.4、修改更新工作内存中的对象修改:用它来为Fact对象指定要修改的字段,并通知Drools引擎发生变化。此方法提供了一种结构化的方式来更新事实。它将更新操作与setter调用结合起来以更改对象字段。2.4.1需求规则1:当工作内存中有火对象Fire,且名称name为空时,触发规则,将火的名称设置为大火。规则二:当火名存在时,输出火名2.4.2drl文件写入packagerulesimportcom.huan.drools.Fireimportcom.huan.drools.Alarmrule"modify_当有火对象时,设置火名"when$fire:Fire(name==null)thenSystem.out.println("1,setfirename");modify($fire){setName("bigfire")}endrule"modify_whenthefireobjecthasanameTrigger"when$fire:Fire(name!=null)thenSystem.out.println("2.名称火灾对象是:“+$fire.getName());end2.4.3部分java文件写成kieSession.insert(newFire());kieSession.fireAllRules(newRuleNameStartsWithAgendaFilter("modify_"));2.4.4运行结果1.设置火种名称2.火种对象名称为:大火2.4.5结论修改会导致模式重新匹配。modify修改工作对象内存中的值。通常,使用修改而不是更新。2.5delete删除工作内存中的对象用法:delete()retract也和delete效果一样,但是推荐delete。3.简单使用drools变量包rulesrule"Useofdrools_variables"wheneval(true)thenSystem.out.println("Matchactivatedcurrenttriggerrule:"+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"););//系统。out.println("获取查询结果:"+drools.getKieRuntime().getQueryResults());结束4。规则继承4.1要求规则一:用户(客户)年龄大于60岁,给予0.9%优惠。规则二:在规则一的基础上,如果用户有车(car),可以免费停车(freeParking)。4.2在drl文件中写入包规则importcom.huan.drools.Customerimportcom.huan.drools.Carrule"rule_extends_rule1"when$c:Customer(age>60)thenmodify($c){setDiscount(0.9)}System.out.println("触发规则一:用户年龄>60岁,获得0.10%优惠");end//规则2继承规则1规则的条件"rule_extends_rule2"extends"rule_extends_rule1"when$car:Car()thenmodify($car){setFreeParking(true)}System.out.println("触发规则2:用户有车,免费停车");到此结束rule_extends_rule2继承了rule_extends_rule1,所以规则A条件也继承了。4.3部分java代码Carcar=newCar();Customercustomer=newCustomer();customer.setAge(65);kieSession.insert(customer);kieSession.insert(car);kieSession.fireAllRules(newRuleNameStartsWithAgendaFilter("rule_extends_"));客户有车,年龄65岁,满足以上规则1和2。4.4运行结果触发规则1:用户年龄>60岁,0.9折触发规则2:用户有车,免费停车4.5结论可以看到在规则上使用extends关键字可以实现规则继承。5、使用do[...]语法改写上面的继承示例5.1需求只要用户年满60岁,直接提供0.9%的折扣。如果还有车,可以免费停车。5.2在drl文件中写入包规则importcom.huan.drools.Customerimportcom.huan.drools.Carrule"Namedresult_rule"when$c:Customer(age>60)do[giveDiscount]//当满足上述条件时执行[giveDiscount]$car:Car()//当这个条件为真时,执行默认值然后执行modify($car){setFreeParking(true)};System.out.println("用户有车,免费停车");然后[giveDiscount]modify($c){setDiscount(0.9)};System.out.println("用户年龄>60岁,立减0.9%");end说明:请参考上面规则文件中5.3节java代码编写Carcar=newCar();Customercustomer=newCustomer();customer.setAge(65);kieSession.insert(customer);kieSession.insert(car);kieSession.fireAllRules(newRuleNameStartsWithAgendaFilter("namingresult_"));5.4运行结果用户年龄>60岁,有车优惠0.10%,免费停车也满足。5.5结论也可以通过在when中使用do[name]然后使用name来实现。6、实现ifelseif的效果6.1需要完成类似ifelseifelse的效果。请参阅下面的各种执行结果。6.2规则文件rule"ifelse-if"when$customer:Customer(age>60)//规则内存中有一个Customer对象,并且age>60if($customer.getLevel()==1)do[level1]//用户级别为1,执行then[level1],然后继续执行下面的条件elseif($customer.getLevel()==2)break[level2]//用户级别为2,执行then[level2],不低于执行的条件elsedo[levelOther]//其他级别,执行then[levelOther],然后执行Car()then下面的条件thenSystem.out.println("Iexecuted");然后[level1]System.out.println("level1");然后[level2]System.out.println("level2");then[levelOther]System.out.println("levelOther");end6.3执行结果图6.4Various执行结果——即上图1的解释,客户年龄小于60。输出:无输出。2.客户年龄大于60,level=1,没有Car。Output:level13.Customer的年龄大于60,level=1,有一辆Car。输出:我执行了level14,客户年龄大于60,level=2,没有Car。Output:level25.顾客年龄大于60,level=2,有一辆Car。输出:level26.客户年龄大于60,level=3,没有Car。输出:levelOther7,Customer年龄大于60且level=3,有Car。输出:levelOther我执行了6.5。do和break和有什么不一样?do:执行完之后,会继续判断后面的执行条件。(即后面的Car判断也会执行,根据是否有Car得到不同的结果)break:执行完成后,不再判断后面的执行条件。(即忽略后面的Car判断,规则已经执行)7.完整代码https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-then8,参考文档1,https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#drl-rules-THEN-con_drl-rules