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

drools的一个简单入门案例

时间:2023-04-01 17:17:55 Java

一、背景最近在学习规则引擎drools。这里简单记录下drools的入门案例。2、为什么要学习drools假设我们有以下场景:我们去商店买衣服的时候,经常会发生这样的事情,买1件没有折扣,买2件有0.98%的折扣,还有购买3件或更多商品可享受0.85%的折扣。那么如果我们要在代码中实现以上功能,是否需要写if...else语句,假设后面规则发生变化,是否需要修改这些if...else语句,然后重新部署程序.这是可能的,但不够优雅。那么我们是否可以将这些业务规则写到规则文件中,规则发生变化后直接修改规则文件呢?而drools可以实现这个功能。三、现实上这个简单的打折案例1、引入jar包org.droolsdrools-bompom7??.69.0.Finalimportorg.droolsdrools-compilerorg.droolsdrools-mvelch.qos。logbacklogback-classic<版本>1.2.112。编写kmodule.xml配置文件这个配置文件需要放在resources/META-INF目录这里需要注意的是kbase下包的值,这个value需要和rules文件中的packagevalues一致,否则会找不到rules,详见下文。三、编写规则文件1、规则文件的语法包名一定要放在第一行package//导入Java的类需要一些全限定名import//定义函数,可选函数//可选//定义query,optionalquery//Optionaldeclare//Optionalglobal//Optional//rulekeyword"rulename"rulenamerule"rulename"//Attributes属性可选when//关键字//Conditions条件,可以为空then//Actions//匹配结束后的执行结果//关键字2.编写规则文件规则文件的名字无所谓,例如:book-discount.drl//包名,一定要防止第一行,这个名字需要要与kbase包中package属性的值一致com.huan.shop/***importclass*/importcom.huan.drools.CustomerOrder//定义rule规则"shop-rule-01"时//模式匹配:到工作内存中查找CustomerOrder,该对象的purchaseQuantity值需要为1,//如果条件为真,$order为绑定变量名,通常以$开头,区分来自事实对象$order:CustomerOrder(purchaseQuantity==1)thenSystem.out.println("Matchingruleshop-rule-01");//赋值,此处赋值后,获取Java代码中的赋值$order.setDiscount(1D);endrule"shop-rule-02"when$order:CustomerOrder(purchaseQuantity==2)thenSystem.out.println("匹配规则shop-rule-02");$order.setDiscount(0.98);endrule"shop-rule-03"when$order:CustomerOrder(purchaseQuantity>=3)thenSystem.out.println("匹配规则shop-rule-03");$order.setDiscount(0.85);结束3。解释一下包名shop-discount.drl从上图我们可以看出是一个规则文件。如果把shop-discount.drl的包名改成com.huan.shop1会提示如下警告:`12:43:01.589[main]WARNorg.drools.compiler.kie.builder.impl.KieBuilderImpl-File'com/huan/shop/shop-discount.drl'在文件夹'com/huan/shop'中,但声明包'com.huan.shop1'。建议在包和文件夹名称之间建立对应关系。`4。编写Java代码1.编写一个订单对象。该对象保存了用户购买的几件衣服以及相应的折扣。/***顾客买衣服的订单,省略了getter和setter方法**@authorhuan.fu*@date2022/5/12-11:27*/publicclassCustomerOrder{/***购买了几个clothes*/private整数purchaseQuantity;/***什么是最终折扣*/privateDoublediscount;publicCustomerOrder(IntegerpurchaseQuantity){this.purchaseQuantity=purchaseQuantity;}}2.编写测试代码1.无状态测试方法statelessSessionTest规则规则2,即最终折扣为0.98。2.stateful测试方法statefulSessionTest规则rule3,即最终折扣0.85。包com.huan.drools;导入org.kie.api.KieServices;导入org.kie.api.event.rule.DebugRuleRuntimeEventListener;导入org.kie.api.runtime.KieContainer;导入org.kie.api.runtime.KieSession;importorg.kie.api.runtime.StatelessKieSession;/***droolstestclass*/publicclassDroolsApplication{publicstaticvoidmain(String[]args)throwsInterruptedException{//无状态会话测试statelessSessionTest();//有状态会话测试statefulSessionTest();}privatestaticvoidstatelessSessionTest(){//获取kie服务KieServiceskieServices=KieServices.get();//获取kie容器对象KieContainerkieContainer=kieServices.getKieClasspathContainer();//获取kiesession,这里是一个无状态会话,因为//intype="stateless"是一个无状态会话StatelessKieSessionkieSession=kieContainer.newStatelessKieSession("shop-ksession");//创建对象,可以理解为Fact对象,即事实对象CustomerOrdercustomerOrder=newCustomerOrder(2);//添加监听器,方便观察日志kieSession.addEventListener(newDebugRuleRuntimeEventListener());//无状态会话只需要执行execute方法kieSession.execute(customerOrder);System.err.println("通过规则后,获得的折扣为:"+customerOrder.getDiscount());}privatestaticvoidstatefulSessionTest(){//获取kie服务KieServiceskieServices=KieServices.get();//获取kie容器对象KieContainerkieContainer=kieServices.getKieClasspathContainer();//获取kiesession,这里是有状态的sessionKieSessionkieSession=kieContainer.newKieSession("shop-ksession-stateful");//创建对象,可以理解为Fact对象,即事实对象CustomerOrdercustomerOrder=newCustomerOrder(3);//添加监听器,方便观察日志kieSession.addEventListener(newDebugRuleRuntimeEventListener());//将customerOrder对象添加到工作内存中kieSession.insert(customerOrder);//触发所有规则,如果只想触发指定规则,使用fireAllRules(AgendaFilteragendaFilter)方法kieSession.fireAllRules();//有状态会话必须调用dispose方法kieSession.dispose();System.err.println("通过规则后得到的折扣为:"+customerOrder.getDiscount());}}这里需要注意statefulsession和statelesssession的区别,一个简单的case实现。6.基本组件droolsengine1.Rules:自己定义的业务规则,比如自己写的规则文件,所有的规则至少要包含触发规则的条件和规则指定的操作2.Productionmemory:存放的位置规则存储在Drools引擎中。3.Facts:在Drools引擎中输入或更改数据,Drools引擎匹配规则条件执行适用的规则。Fact对象的值在规则中被修改,并且realJavaBean的数据也会发生变化,例如:当我们调用ksession.insert(object)时,插入的对象可以理解为一个Facts对象4.工作内存:Drools引擎中存储facts的位置5.模式匹配器:匹配6.议程:议程:执行在议程规则中激活的已排序项目。七、完整代码https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-quickstart八、参考文档1,https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#decision-engine-con_decision-engine