当前位置: 首页 > news >正文

外贸网站seo优化山西建站推广

外贸网站seo优化,山西建站推广,轻网站怎么建立,怎样查网站空间地址用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能#xff0c;我们要如何开始#xff1f;你无须担心#xff0c;这些复杂性是分层的#xff0c;你可以用简单的用例来逐步入门。 无状态Session#xff0c;无须使用推理#xff0c;就形成了最简单的用…用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能我们要如何开始你无须担心这些复杂性是分层的你可以用简单的用例来逐步入门。 无状态Session无须使用推理就形成了最简单的用例。一个无状态session可以经过一个函数然后返回一些结果。无状态session的用例都具有但不限于如下功能 校验 此人是否有资格申请抵押贷款 计算 计算抵押溢价 路由和过滤 将传入的邮件如电子邮件过滤到文件夹中 将传入的消息发送到目的地 让我们从一个简单的例子开始使用一个驾驶执照申请。 public class Applicant {private String name; private int age; private boolean valid; // getter and setter methods here } 根据上面的数据模型我们为它添加一个规则18岁以下的申请人会被拒绝。 package com.company.licenserule Is of valid age when$a : Applicant( age 18 ) then$a.setValid( false ); end 为了使规则引擎能够识别数据从而能够针对一些规则进行处理我们需要 插入 数据就像一个数据库一样。当Applicant实例被插入到引擎时首先会校验约束条件在这个用例中只有两个约束条件。之所以说是两个规则其一是Applicant的类型校验其二是age 18的规则校验。一个对象类型加上它的另个或多个字段约束称为模式。当插入的实例同时满足这两个约束时那么认为实例能够匹配这一规则。 $a是一个绑定变量它允许我们引用匹配约束的对象实例。这一实例的属性在then后面会被更新$符号是可选的但它能够帮助用来从不同的字段名中区分不同的变量名。仅仅处理被插入的数据中能够匹配模式的数据的这种做法我们称为模式匹配。 在Drools文件中推入规则是十分必要的它只是一个普通的文本文件只是后缀名是 .drl它是 Drools Rule Language 的简称。那么让我们来调用一下文件 licenseApplication.drl 然后在Kie Project中保存。 Kie Project具有一个正常的Maven项目结构还一个附加的定义了KieBases 和 KieSession 的 kmodule.xml文件。这个文件必须放在Maven项目的resources / META-INF文件夹中而包含前一个规则的所有其他Drools构件如licenseApplication.drl必须存储在资源文件夹或其下的任何其他子文件夹中。 由于所有配置方面都提供了有意义的默认值所以最简单的kmodule.xml文件只需包含一个空的kmodule标签如下所示 ?xml version1.0 encodingUTF-8? kmodule xmlnshttp://www.drools.org/xsd/kmodule/ 在这一点上可以创建一个KieContainer来从类路径中读取要生成的文件。 KieServices kieServices KieServices.Factory.get(); KieContainer kContainer kieServices.getKieClasspathContainer(); 上面的代码片段编译了在classpath中找到的所有DRL文件并把这个编译的结果一个KieModule放到KieContainer中。 如果没有错误我们将准备从“KieContainer”创建会话并针对一些数据执行 StatelessKieSession kSession kContainer.newStatelessKieSession(); Applicant applicant new Applicant( Mr John Smith, 16 ); assertTrue( applicant.isValid() ); ksession.execute( applicant ); assertFalse( applicant.isValid() ); 上面的代码根据规则执行数据。 由于申请人年龄在18岁以下申请被标记为无效。 到目前为止我们只使用了一个实例但如果我们想要使用多个实例呢 我们可以针对任何实现Iterable的对象执行比如集合。 让我们添加另一个名为“Application”的类它具有应用程序的日期我们也将布尔有效字段移动到“Application”类。 public class Applicant {private String name; private int age; // getter and setter methods here } public class Application { private Date dateApplied; private boolean valid; // getter and setter methods here } 我们还会添加另一条规则来验证申请是在一段时间内完成的。 package com.company.licenserule Is of valid age whenApplicant( age 18 ) $a : Application() then $a.setValid( false ); end rule Application was made this year when $a : Application( dateApplied 01-jan-2009 ) then $a.setValid( false ); end 不幸的是Java数组并没有实现 Iterable 接口所以我们必须使用JDK转换器方法 Arrays.asList…​。 下面显示的代码针对可迭代的列表执行在列表中插入所有集合元素然后再触发任何匹配的规则。 StatelessKieSession kSession kContainer.newStatelessKieSession(); Applicant applicant new Applicant( Mr John Smith, 16 ); Application application new Application(); assertTrue( application.isValid() ); ksession.execute( Arrays.asList( new Object[] { application, applicant } ) ); assertFalse( application.isValid() ); executeObject object 和 executeIterable objects ) 是接口BatchExecutor方法 executeCommand command 的两个实现方法。 像KIE API的所有其他工厂一样可以从 KieServices 获得的 KieCommands 命令工厂用于创建命令以下相当于 executeIterable it ksession.execute( kieServices.getCommands().newInsertElements( Arrays.asList( new Object[] { application, applicant } ) ); 批处理执行程序和命令工厂在使用多个命令和输出标识符来获取结果时特别有用。 KieCommands kieCommands kieServices.getCommands(); ListCommand cmds new ArrayListCommand(); cmds.add( kieCommands.newInsert( new Person( Mr John Smith ), mrSmith, true, null ) ); cmds.add( kieCommands.newInsert( new Person( Mr John Doe ), mrDoe, true, null ) ); BatchExecutionResults results ksession.execute( kieCommands.newBatchExecution( cmds ) ); assertEquals( new Person( Mr John Smith ), results.getValue( mrSmith ) ); CommandFactory 支持许多其他可以在 StartProcess  Query 和 SetGlobal 的 BatchExecutor 中使用的命令。 有状态的知识Session 有状态会话很长时间并允许随着时间的推移进行迭代更改。有状态会话的一些常见用例包括但不限于 监测 半自动买入的股市监测和分析 诊断 故障查找医疗诊断 物流 包裹跟踪和交付供应 合规性 验证市场交易的合法性 与无状态会话相比之后必须调用dispose方法以确保没有内存泄漏因为KieBase在创建时包含对有状态知识会话的引用。由于有状态知识会话是最常用的会话类型因此它在KIE API中被命名为KieSession。KieSession还支持BatchExecutor接口就像StatelessKieSession一样唯一的区别是FireAllRules命令不会在有状态会话结束时自动调用。 我们以举一个火警的例子来说明监控用例。我们只用四个类代表一间房子里的房间每间房子里有一个洒水器。如果一个房间发生火灾我们用一个“Fire”实例来表示。 public class Room {private String name // getter and setter methods here } public class Sprinkler { private Room room; private boolean on; // getter and setter methods here } public class Fire { private Room room; // getter and setter methods here } public class Alarm { } 在前面关于无状态会话的章节中介绍了插入和匹配数据的概念。 这个例子假设每个对象类型只有一个实例被插入因此只能使用字面约束。 然而房子有很多房间所以规则必须表达物体之间的关系比如喷洒器在某个房间里。 这最好通过使用绑定变量作为模式中的约束来完成。 这个“加入”过程产生了所谓的交叉产品这在下一节将会介绍。 发生火灾时会为该房间创建Fire类的实例并将其插入会话中。 该规则在Fire对象的room字段上使用绑定来约束与当前关闭的房间的喷洒器的匹配。 当这个规则触发并且结果被执行时喷淋器被打开。 rule When there is a fire turn on the sprinkler whenFire($room : room)$sprinkler : Sprinkler( room $room, on false ) then modify( $sprinkler ) { setOn( true ) }; System.out.println( Turn on the sprinkler for room $room.getName() ); end 而无状态会话使用标准的Java语法来修改一个字段而在上面的规则中我们使用modify语句它作为一种“with”语句。它可能包含一系列逗号分隔的Java表达式即对由modify语句的控制表达式选择的对象的设置者的调用。这会修改数据并使引擎知道这些更改以便再次推理它们。这个过程被称为推理对有状态会话的工作是必不可少的。无状态会话通常不使用推理因此引擎不需要知道数据的更改。也可以通过使用sequential mode显式关闭推理。 到目前为止我们有规则告诉我们什么时候匹配数据存在但是什么时候存在not呢 我们如何确定火已被扑灭即不存在一个Fire对象了吗 以前约束条件是根据命题逻辑的句子其中引擎限制个别情况。 Drools的也有一阶逻辑的支持可以让你看的数据集。 当不存在某个关键字时关键字“not”下的模式匹配。 一旦房间里的火已经消失下面给出的规则就会使喷洒器关闭。 rule When the fire is gone turn off the sprinkler when$room : Room( )$sprinkler : Sprinkler( room $room, on true )not Fire( room $room ) then modify( $sprinkler ) { setOn( false ) }; System.out.println( Turn off the sprinkler for room $room.getName() ); end 每个房间有一个洒水喷头这个建筑物只有一个警报。 发生火灾时会产生一个“Alarm”对象但无论发生多少火灾整个建筑物只需要一个“Alarm”。 以前没有引入“not”来匹配事实; 现在我们使用它的补充“exists”来匹配某个类别的一个或多个实例。 rule Raise the alarm when we have one or more fires whenexists Fire() theninsert( new Alarm() ); System.out.println( Raise the alarm ); end 同样当没有火灾时我们要删除警报所以not关键字可以再次使用。 rule Cancel the alarm when all the fires have gone whennot Fire()$alarm : Alarm() then delete( $alarm ); System.out.println( Cancel the alarm ); end 最后当应用程序首次启动时以及在警报被移除并且所有洒水喷头已关闭之后都会打印一般健康状态消息。 rule Status output when things are ok whennot Alarm()not Sprinkler( on true ) then System.out.println( Everything is ok ); end 正如我们在无状态会话中所做的那样上面的规则应该放在一个DRL文件中并保存到Maven项目或其任何子文件夹的资源文件夹中。 和以前一样我们可以从KieContainer中获得一个KieSession。 唯一不同的是这一次我们创建了一个有状态会话而在此之前我们创建的是一个无状态会话。 KieServices kieServices KieServices.Factory.get(); KieContainer kContainer kieServices.getKieClasspathContainer(); KieSession ksession kContainer.newKieSession(); 随着会话创建现在可以反复使用它随着时间的推移。 创建并插入四个Room对象以及每个房间的一个sprinkler对象。 在这一点上引擎已经完成了所有的匹配但是还没有任何规则被解雇。 调用ksession.fireAllRules允许匹配的规则触发但没有火灾只会产生健康信息。 String[] names new String[]{kitchen, bedroom, office, livingroom}; MapString,Room name2room new HashMapString,Room(); for( String name: names ){ Room room new Room( name ); name2room.put( name, room ); ksession.insert( room ); Sprinkler sprinkler new Sprinkler( room ); ksession.insert( sprinkler ); } ksession.fireAllRules(); Everything is ok 我们现在创建两个大火并插入它们; 这次为返回的FactHandle保留一个引用。 事实句柄是插入实例的内部引擎引用允许实例在稍后的时间点收回或修改。 现在发动机发生火灾一旦调用了fireAllRules报警就会被触发相应的喷淋头就会打开。 Fire kitchenFire new Fire( name2room.get( kitchen ) ); Fire officeFire new Fire( name2room.get( office ) );FactHandle kitchenFireHandle ksession.insert( kitchenFire ); FactHandle officeFireHandle ksession.insert( officeFire );ksession.fireAllRules(); Raise the alarmTurn on the sprinkler for room kitchenTurn on the sprinkler for room office 过了一段时间后火势将会消失Fire实例将被收回。 这导致洒水器关闭警报被取消最终再次打印健康信息。 ksession.delete( kitchenFireHandle ); ksession.delete( officeFireHandle );ksession.fireAllRules(); Cancel the alarmTurn off the sprinkler for room officeTurn off the sprinkler for room kitchenEverything is ok 这并不难我希望你能开始看到声明式规则系统的价值和威力。 方法与规则 人们经常混淆方法和规则而新规则用户经常会问“我怎样称呼规则” 在上一节之后你现在的感觉就像一个规则专家答案是显而易见的但我们仍然总结的差异。 public void helloWorld(Person person) { if ( person.getName().equals( Chuck ) ) { System.out.println( Hello Chuck ); } } 方法直接调用。 特定的实例通过。 一次调用会导致一次执行。 rule Hello World whenPerson( name Chuck ) then System.out.println( Hello Chuck ); end 规则通过匹配任何数据执行只要它插入引擎。 规则永远不能直接调用。 特定的实例不能传递给规则。 根据比赛情况规则可能会触发一次或几次或根本不触发。 交叉产品 早些时候提到了“交叉产品”这个词这是加入的结果。 想象一下来自火灾报警示例的数据与没有字段限制的下列规则结合使用 rule Show Sprinklers when$room : Room()$sprinkler : Sprinkler() thenSystem.out.println( room: $room.getName() sprinkler: $sprinkler.getRoom().getName() ); end 用SQL语言来说就像在Room, Sprinkler中执行select *一样Room表中的每一行都将与Sprinkler表中的每一行连接在一起产生以下输出 room:office sprinkler:office room:office sprinkler:kitchen room:office sprinkler:livingroom room:office sprinkler:bedroom room:kitchen sprinkler:office room:kitchen sprinkler:kitchen room:kitchen sprinkler:livingroom room:kitchen sprinkler:bedroom room:livingroom sprinkler:office room:livingroom sprinkler:kitchen room:livingroom sprinkler:livingroom room:livingroom sprinkler:bedroom room:bedroom sprinkler:office room:bedroom sprinkler:kitchen room:bedroom sprinkler:livingroom room:bedroom sprinkler:bedroom 这些交叉产品显然可能变得庞大并且可能包含虚假数据。 交叉产品的大小通常是新规则制定者性能问题的来源。 由此可以看出限制交叉产品总是可取的这是通过可变约束来完成的。 rule when$room : Room()$sprinkler : Sprinkler( room $room ) thenSystem.out.println( room: $room.getName() sprinkler: $sprinkler.getRoom().getName() ); end 这使得只有四行数据每个房间都有正确的喷淋头。 在SQL实际上是HQL中相应的查询将是select * from Room, Sprinkler where Room Sprinkler.room。 room:office sprinkler:office room:kitchen sprinkler:kitchen room:livingroom sprinkler:livingroom room:bedroom sprinkler:bedroom 执行控制 议程 议程是一个Rete功能。 它维护一组能够执行的规则其工作是按照确定的顺序安排执行。 在RuleRuntime操作期间规则可能完全匹配并有资格执行; 单个规则运行时操作可能会导致多个符合条件的规则。 当规则完全匹配时创建规则匹配引用规则和匹配的事实并放置到议程中。 议程使用冲突解决策略控制这些匹配的执行顺序。 引擎反复循环两个阶段 1.规则运行时操作。 这是大部分工作发生的地方无论是在结果RHS本身还是主要的Java应用程序过程中。 一旦结果完成或主Java应用程序进程调用fireAllRules()引擎就切换到议程评估阶段。 2.议程评估。 这试图选择一个规则来触发。 如果没有找到规则则退出否则会触发找到的规则将阶段切换回规则运行时操作。 Figure 1. Two Phase Execution 这个过程重复直到议程清晰在这种情况下控制返回到调用应用程序。 当规则运行时操作正在发生时没有规则被触发。 规则匹配和冲突集 现金流量示例 到目前为止数据和匹配过程是简单而小巧的。 为了将事情混合起来我们将探索一个新的例子来处理日期期间的现金流量计算。 发动机的状态将在关键阶段示例性地示出以帮助更好地理解发动机罩下的实际情况。 将使用三个类如下所示。 这将有助于我们增加对模式匹配的理解并进一步加入。 然后我们将用这个来说明执行控制的不同技术。 public class CashFlow {private Date date; private double amount; private int type; long accountNo; // getter and setter methods here } public class Account { private long accountNo; private double balance; // getter and setter methods here } public AccountPeriod { private Date start; private Date end; // getter and setter methods here } 现在您已经知道如何创建KieBases以及如何实例化事实来填充KieSession所以将使用表来显示插入的数据的状态因为它使事情变得更加清楚。 下表显示为“Account”插入单个事实。 还插入了一系列借方和贷方作为该账户的“CashFlow”对象延伸了两个季度。 Figure 2. CashFlows and Account 两个规则可以用来确定该季度的借方和贷方并更新账户余额。 以下两条规则限制了给定时间段内某个账户的现金流量。 请注意使用简短语法的“”以避免两次重复字段名称。 select * from Account acc, Cashflow cf, AccountPeriod ap where acc.accountNo cf.accountNo and cf.type CREDIT and cf.date ap.start and cf.date ap.end trigger : acc.balance cf.amount select * from Account acc, Cashflow cf, AccountPeriod ap where acc.accountNo cf.accountNo and cf.type DEBIT and cf.date ap.start and cf.date ap.end trigger : acc.balance - cf.amount 如果AccountPeriod设置为第一季度我们将限制增加贷方余额的规则在两行数据上触发减少借方余额以对一行数据进行操作。 Figure 3. 会计周期现金流量和账户 上面的两个现金流量表代表两个规则的匹配数据。 数据在插入阶段被匹配正如你在上一章中发现的那样它不会直接触发而只是在fireAllRules()被调用之后。 同时规则及其匹配的数据被放置在议程上并被称为“行为匹配”或“规则实例”。 议程是一个规则匹配表只要fireAllRules()被调用它就能够触发并执行其后果。 议程上的规则匹配被称为冲突集其执行是由冲突解决策略决定的。 请注意到目前为止的执行顺序被认为是任意的。 Figure 4. 现金流和账户 所有上述激活的规则被执行后账户的余额为-25。 Figure 5. 现金流和账户 如果账户期限更新到第二季度我们只有一行匹配的数据因此在议程上只有一个规则匹配。 规则执行的结果导致了25的余额。 Figure 6. 现金流和账户 Figure 7. 现金流和账户 解决冲突 如果你不希望规则执行的顺序是任意的呢 如果议程上有一个或多个规则匹配则说明它们之间存在冲突并使用冲突解决策略来确定执行顺序。 Drools战略非常简单基于一个显着的价值它为一个规则赋予了优先权。 每个规则的默认值为0值越高优先级越高。 作为一般规则不要指望以任何特定顺序开火的规则并且制定规则而不必担心“flow”。 然而当需要流程时除了显着性之外还有许多可能性议程组规则流程组激活组和控制/信号量事实。 Drools 6.0 规则根据源文件中的salience之后的数字来确定优先级。 Salience 为了说明salience我们添加一个规则来打印帐户余额我们希望在对所有帐户应用所有借记和贷项之后执行此规则。 我们通过给这个规则分配一个负的salience来达到这个目的以便在默认salience 0的所有规则之后触发。 rule Print balance for AccountPeriodsalience -50whenap : AccountPeriod()acc : Account()thenSystem.out.println( acc.accountNo : acc.balance ); end 下表描述了由此产生的议程。 这三个借记和贷记规则显示为任意顺序而打印规则排在最后以后执行。 Figure 8. 现金流和账户 议程组agenda group 议程组允许您将规则放入组中并将这些组放入堆栈。 该堆栈有push/pop 的能力。 调用“setFocus”将组放入堆栈 ksession.getAgenda().getAgendaGroup( Group A ).setFocus(); 议程总是评估堆栈的顶部。 当所有的规则已经为一个组激发它从堆栈弹出并评估下一个组。 rule increase balance for creditsagenda-group calculation whenap : AccountPeriod()acc : Account( $accountNo : accountNo )CashFlow( type CREDIT,accountNo $accountNo,date ap.start ap.end,$amount : amount ) thenacc.balance $amount; end rule Print balance for AccountPeriodagenda-group report whenap : AccountPeriod()acc : Account() thenSystem.out.println( acc.accountNo : acc.balance ); end 首先把重点放在“report”组然后把重点放在“calculation”上我们确保首先评估组。 Agenda agenda ksession.getAgenda(); agenda.getAgendaGroup( report ).setFocus(); agenda.getAgendaGroup( calculation ).setFocus(); ksession.fireAllRules(); 规则流程 Drools还具有ruleflow-group属性允许工作流程图声明性地指定何时允许激发规则。 下面的截图是从Eclipse使用Drools插件。 它有两个规则流组节点确保计算规则在报告规则之前执行。 在规则中使用ruleflow-group属性如下所示。 rule increase balance for creditsruleflow-group calculation whenap : AccountPeriod()acc : Account( $accountNo : accountNo )CashFlow( type CREDIT,accountNo $accountNo,date ap.start ap.end,$amount : amount ) thenacc.balance $amount; end rule Print balance for AccountPeriodruleflow-group report whenap : AccountPeriod()acc : Account() thenSystem.out.println( acc.accountNo : acc.balance ); end 推理 巴士通行证例子 现在推论有一个不好的名字因为它与业务用例无关而且太复杂而无用。 的确人为的和复杂的例子都是在推论中出现的但是这也不应该损害简单有用的存在。 但更重要的是正确使用推理可以提供更敏捷更不容易出错的业务规则这些规则更容易维护。 那么推理是什么 当我们通过使用以前的知识获得某些东西的知识时就会推断出什么 例如给定一个具有年龄字段和规定年龄政策控制的规则的人的事实我们可以推断出一个人是成年人还是孩子并据此采取行动。 rule Infer Adult when$p : Person( age 18 ) theninsert( new IsAdult( $p ) ) end 由于前面的规则每个18岁以上的人都会为他们插入一个IsAdult的实例。 这个事实是特殊的因为它被称为关系。 我们可以在任何规则中使用这个推断关系 $p : Person() IsAdult( person $p ) 所以现在我们知道推论是什么并且有一个基本的例子这是如何促进良好的规则设计和维护 让孩子成年后负责发放身份证的政府部门以下简称ID部门。 他们可能有一个决策表其中包括这样的逻辑它说当一个在伦敦的成年人是18岁或以上发卡 但身份证件部门并没有制定成人的政策。这是在中央政府一级完成的。如果中央政府将这个年龄改为21岁这将启动变革管理过程。有人必须联系身份证件部门确保他们的系统得到更新以便法律上线。 这种变更管理流程和部门之间的沟通对于敏捷环境来说并不理想而且变更成本高昂且容易出错。此外信用卡部门正在管理更多的信息而不是需要通过其“规模管理”的“单一”方法意识到这一点。我的意思是它并不关心明确的年龄 18信息决定某人是否是成年人而只关心他们是否是成年人。 相比之下让我们采取一种方法将创作责任分开脱离使中央政府和身份证部门都保持自己的规则。 确定谁是成年人是中央政府的工作。 如果他们改变法律他们只是用新的规则来更新他们的中央仓库 如前所述IsAdult事实是从政策规则中推断出来的。 它封装了看似随意的一段逻辑时间▸ 18并为其含义提供了语义抽象。 现在如果有人使用上述规则他们不再需要知道明确的信息决定某人是否是成年人。 他们可以使用推断的事实 虽然这个例子是非常微小的但它说明了一些重要的观点。我们从知识工程的单一和漏洞入手开始。我们创建了一个包含所有可能的信息的决策表泄露了ID部门不关心也不想管理的来自中央政府的信息。 我们首先将知识过程分离开来这样每个部门只负责知道什么。然后我们使用推断的事实IsAdult封装了这个变动的知识。术语IsAdult的使用还给以前的任意逻辑时间▸ 18提供了语义抽象。 所以在进行知识工程时一般的经验法则是 坏的 单一Monolithic 泄露Leaky 好的 解除对知识的责任 封装知识 为这些封装提供语义抽象 用逻辑对象维护真相 概述 定期插入后你必须明确地收回事实。有了逻辑断言断言的事实将会自动撤回因为断言它的条件不再是真实的。实际上它更加聪明因为只有当没有任何单一条件支持逻辑断言时才会收回。 声明一个正规的插入就像“陈述事实”所暗示的直觉意义一样。使用一个HashMap和一个计数器我们追踪一个特定的平等是多少次;这意味着我们计算有多少不同的实例是相等的。 当我们在RHS执行期间逻辑插入一个对象的时候我们被说成是正当的并且被认为是通过触发规则来证明的。对于每个逻辑插入只能有一个相等的对象并且每个随后的相等的逻辑插入增加该逻辑断言的对齐计数器。创建规则的LHS取消了正当理由计数器也相应减少。一旦我们没有更多的理由逻辑对象自动收回。 如果我们尝试逻辑插入一个对象时有一个相等的声明对象这将失败并返回null。如果我们声明一个对象具有一个现有的平等的对象我们重写事实;这个覆盖如何工作取决于配置设置WM_BEHAVIOR_PRESERVE。当属性设置为discard时我们使用现有的句柄并用新的对象替换现有的实例这是默认行为;否则我们重写它同时我们创建一个新的FactHandle。 这可能会在第一次阅读时感到困惑所以希望下面的流程图有所帮助。当它说它返回一个新的FactHandle时这也表示对象是通过网络传播的。 Figure 9. 声明插入 Figure 10. 逻辑插入 有推理和TMS的公共汽车通行证例子 前面的例子是发行身份证超过18岁在这个例子中我们现在发行巴士通行证无论是儿童或成人通行证。 rule Issue Child Bus Pass when$p : Person( age 16 ) theninsert(new ChildBusPass( $p ) ); end rule Issue Adult Bus Pass when $p : Person( age 16 ) then insert(new AdultBusPass( $p ) ); end 像以前一样上面的例子被认为是单一的漏洞和提供差的关注分离。 像以前一样我们可以提供一个更强大的应用程序使用推理来区分问题。注意这次我们不只是插入推断的对象我们使用“insertLogical” rule Infer Child when$p : Person( age 16 ) theninsertLogical( new IsChild( $p ) ) end rule Infer Adult when $p : Person( age 16 ) then insertLogical( new IsAdult( $p ) ) end “insertLogical”是Drools真相维护系统TMS的一部分。当一个事实被逻辑插入时这个事实取决于“when”从句的真实性。这意味着当规则成为错误时事实会自动收回。由于这两个规则是相互排斥的所以这个效果特别好。所以在上面的规则中如果这个人在16岁以下它会插入一个IsChild的事实一旦这个人是16岁或以上IsChild的事实就会自动收回并且插入了IsAdult的事实。 回到代码发出巴士通行证这两个规则可以在逻辑上插入ChildBusPass和AdultBusPass事实因为TMS 支持链接一系列级联的逻辑插入。 rule Issue Child Bus Pass when$p : Person( )IsChild( person $p ) theninsertLogical(new ChildBusPass( $p ) ); endrule Issue Adult Bus Pass when $p : Person( age 16 ) IsAdult( person $p ) then insertLogical(new AdultBusPass( $p ) ); end 现在当一个人从15岁变成16岁时不仅IsChild事实自动缩回他的ChildBusPass事实也是如此。对于奖励积分我们可以将这个与not条件元素结合起来处理通知在这种情况下请求返回通行证。所以当TMS自动收回ChildBusPass对象时这个规则触发并发送一个请求给这个人 rule Return ChildBusPass Request when$p : Person( )not( ChildBusPass( person $p ) ) thenrequestChildBusPass( $p ); end 重要说明Java对象的等价 注意到真理维护和逻辑断言完全可以工作这是很重要的你的Fact对象可能是JavaBeans必须正确地覆盖equals和hashCode方法来自java.lang.Object。由于事实维护系统需要知道两个不同物理对象的值是否相等因此按照Java标准必须正确覆盖both等于和hashCode。 两个对象是相等的当且仅当它们的equals方法相互返回true并且它们的hashCode方法返回相同的值。有关更多详细信息请参阅Java API但请记住MUST必须覆盖equals和hashCode。 TMS行为不受标识vs等价的时间配置的影响TMS始终是等价的。 从工作记忆中删除陈述或逻辑断言 默认情况下当从工作记忆中删除一个事实时Drools尝试从既定事实集合中删除它并且在逻辑断言的情况下也从真值维护系统TMS中删除它。但是使用delete方法的重载也可以只从2.中删除它。例如调用 ksession.delete( factHandle, FactHandle.State.LOGICAL ); 这个事实只有在逻辑断言的情况下才会被删除但是如果它是一个陈述的事实则不会被删除。在这种情况下如果事实已经说明了它的删除失败了并且被忽略了。 电子表格中的决策表 决策表是一种“精确而紧凑”参考自Wikipedia表示条件逻辑的方式非常适合商业级规则。 Drools支持电子表格格式的管理规则。支持的格式是ExcelXLS和CSV这意味着可以使用各种电子表格程序例如Microsoft ExcelOpenOffice.org Calc等。预计基于网络的决策表编辑器将被包括在不久的将来版本中。 决策表是一个旧的概念用软件来说但是多年来已经证明是有用的。简而言之在Drools中决策表是一种生成从输入到电子表格中的数据驱动的规则的方法。数据采集和处理的电子表格的所有常用功能都可以利用。 何时使用决策表 如果存在可以表示为规则模板和数据的规则则将决策表视为一个行为过程决策表的每一行都提供与模板结合生成规则的数据。 许多企业已经使用电子表格来管理数据计算等。如果您乐于继续这种方式您也可以通过这种方式来管理您的业务规则。这也假设您很乐于在xls或csv文件中管理规则包。决策表不建议用于不遵循一组模板的规则也不建议使用少量规则或者对Excel或OpenOffice.org等软件不喜欢。它们是理想的可以控制规则的参数可以编辑而不需要直接暴露规则。 决策表还提供了一定程度的基础对象模型的隔离。 概述 下面是一些真实世界决策表的例子稍作修改以保护无辜者。 Figure 11. 使用Excel来编辑决策表 Figure 12. 一个规则行中多种行为 Figure 13. 使用OpenOffice.org 在上面的例子中决策表的技术方面已经崩溃了使用标准的电子表格功能。 规则从第17行开始每一行产生一个规则。条件在列CDE等中动作在屏幕外。单元格中的值非常简单它们的含义由行16中的标题指示。列B只是一个描述。通常使用颜色来明确表格的不同区域的含义。   请注意虽然决策表看起来像自上而下但情况并非如此。理想情况下规则的编写不考虑行的顺序仅仅因为这使得维护更容易因为行不需要一直移动。 由于每一行都是一个规则所以适用相同的原则。由于规则引擎处理事实任何匹配的规则都可能触发。 有些人对此感到困惑在规则触发时模拟一个非常简单的决策表就可以清除议程只有第一个匹配才会执行一个动作。另请注意在一个电子表格中可以有多个表。这样可以将规则分组在共享通用模板的位置然而在一天结束时它们全部组合成一个规则包。决策表本质上是一种自动生成DRL规则的工具。 Figure 14. 使用多个表进行分组的规则 决策表如何工作 要记住的关键是决策表中的每一行都是一个规则该行中的每一列都是该规则的条件或动作。 Figure 15. 行和列 电子表格查找RuleTable关键字以指示规则表起始行和列的开始。 其他关键字也用于定义其他包级别属性稍后介绍。 将关键字保留在一列是很重要的。 按照惯例第二列“B”用于这个但它可以是任何列约定左边留有空白的备注。 在下面的图中C实际上是它开始的列。 左边的所有内容都被忽略。 如果我们扩大隐藏的部分它开始变得更有意义它是如何工作的; 请注意C列中的关键字。 Figure 16. 展开规则模板 现在可以看到使其工作的隐藏的魔法。 RuleSet关键字指示将在rule package中使用的名称该名称将包含所有规则。 此名称是可选的使用默认值但必须在单元格右边有RuleSet关键字。 列C中可见的其他关键字是“导入”和“顺序”稍后将对其进行介绍。 RuleTable关键字是很重要的因为它表示将遵循一些规则基于一些规则模板。 RuleTable关键字后面有一个名称用于为生成的规则的名称添加前缀。 附加表单名称和行号以保证唯一的规则名称。   与表格名称结合使用的表格名称在同一KieBase中的所有电子表格文件中必须是唯一的。 如果不是这样一些规则可能会有相同的名称只有其中一个会被应用。 要显示这样被忽略的规则https://docs.jboss.org/drools/release/7.4.1.Final/drools-docs/html_single/index.html#_changingthedefaultbuildresultresultseverity [引发此类规则名称冲突的严重性]。 RuleTable的列表示规则开始的列; 左侧的列将被忽略。   通常关键字组成名称 - 值对。 参考第14行RuleTable之后的那一行关键字CONDITION和ACTION表示下面各列中的数据适用于规则的LHS部分或RHS部分。 规则上还有其他属性也可以选择这种方式设置。 第15行包含ObjectTypes的声明。 该行中的内容是可选的但是如果该选项未被使用则该行必须留空; 然而这个选项通常被认为是相当有用的。 使用此行时下面单元格第16行中的值将成为该对象类型的约束。 在上面的例子中它生成了“Personage ”42“”和“Cheesetype ”stilton“”其中42和“stilton”来自第18行。 “”是隐含的; 如果只给出一个字段名称翻译者就会假定它是生成完全匹配的。   一个ObjectType声明可以跨越列通过合并的单元格这意味着合并范围以下的所有列将被合并到一个模式中一次匹配一个事实的一个模式中而非包含 相同的ObjectType但导致不同的模式可能匹配不同或相同的事实。 第16行包含规则模板本身。 他们可以使用“$ param”占位符来表示下面单元格的数据应该插入的位置。 对于多次插入请使用“$ 1”“$ 2”等表示下面单元格中逗号分隔列表中的参数。 它可能包含该栏目的文字说明。 行18和行19显示的数据将与行15中的模板组合插值以生成规则。 如果一个单元格不包含数据则其模板将被忽略。 这意味着某些条件或操作不适用于该规则行。读取规则行直到出现空行。 一张表中可以存在多个RuleTables。 第20行包含另一个关键字和一个值。 像这样的关键字的行位置并不重要大多数人把它们放在顶部但是它们的列应该与RuleTable或RuleSet关键字出现的位置相同。 在我们的情况下列C被选择为重要的但是可以使用任何其他列。 在上面的例子中规则会像下面一样呈现因为它使用“ObjectType”行 //row 18 rule Cheese_fans_18 whenPerson(age42) Cheese(typestilton) then list.add(Old man stilton); end   “age ”42“”和“type ”stilton“”的约束被解释为单个约束被添加到上面单元格的相应ObjectType中。 如果上面的单元格是跨越的那么在一个“列”上可能有多个约束。   非常大的决策表可能有非常大的内存要求。 电子表格语法 电子表格结构 有两种类型的矩形区域定义用于生成DRL文件的数据。 一个由标记为“RuleSet”的单元标记定义除规则以外的所有DRL项目。 另一个可能会重复发生并且位于以“RuleTable”开头的单元格的右下方。 这些领域代表了实际的决策表每个领域产生了一套类似结构的规则。 一个规则集区域可以包含单元对一个在RuleSet下面包含一个关键字指定在同一行中的另一个关键字中包含的值。 规则表区域的列定义了从中派生的规则左侧的模式和约束规则后果的动作以及单个规则属性的值。因此规则表区域应该包含一个或多个列条件和操作以及规则属性的列的任意选择每个列最多一列。前面四行跟着标记有“RuleTable”单元格的行被标记为标题区域主要用于定义构建规则的代码。它是这四个标题行下面的任何额外的行产生另一个规则其数据提供规则表标题中定义的代码的变化。 所有关键字不区分大小写。 只有第一张工作表被检查决策表。 规则集条目 规则集区域中的条目可以定义DRL构造规则除外并指定规则属性。 尽管可以重复使用结构的条目但是每个规则属性最多只能给出一次并且它适用于所有规则除非它被“规则表”区域内定义的相同属性取代。 条目必须以垂直堆叠的单元对序列给出。 第一个包含关键字和右边的值如下表所示。 只要由“RuleSet”标记的列被维护为包含关键字的那一列这个单元格对的序列就可以被空行或甚至规则表中断。 Table 1. 规则集区域中的条目 关键字 值 用法 RuleSet 生成的DRL文件的包名称。可选默认是lele_table。 必须是第一个入口。 Sequential true or false. 如果是“true”则使用显着性来确保规则从上到下起火。 可选最多一次。如果省略则不执行射击命令。 SequentialMaxPriority 整数数值 可选最多一次。在顺序模式下此选项用于设置突出显示的起始值。如果省略则默认值为65535。 SequentialMinPriority 整数数值 可选最多一次。在顺序模式下此选项用于检查是否违反了最小显着性值。如果省略则默认值为0。 EscapeQuotes true or false. 如果是“true”那么引号就会被转义从而在DRL中出现。 可选最多一次。如果省略引号将被转义。 NumericDisabled true or false. 如果是“true”则字符串表示形式用于DRL而不是来自Numeric单元格的double值可选最多一次。如果省略则使用double值。 Import 要导入的Java类的逗号分隔列表。 可选可以重复使用。 变量 DRL全局变量的声明即一个后跟一个变量名的类型。多个全局定义必须用逗号分隔。 可选可以重复使用。 Variables DRL全局变量的声明即一个后跟一个变量名的类型。多个全局定义必须用逗号分隔。 可选可以重复使用。 Functions 一个或多个函数定义根据DRL语法。 可选可以重复使用。 Queries 一个或多个查询定义根据DRL语法。 可选可以重复使用。 Declare 在某些语言环境中MS OfficeLibreOffice和OpenOffice会对不同的双引号进行编码这会导致编译错误通常很难看出差异例如“A”会失败 但A会起作用。   要定义适用于生成的DRL文件中所有规则的规则属性可以使用下表中的任何条目。 但是请注意必须使用正确的关键字。 而且每个属性只能使用一次。 Table 2. 规则集区域中的规则属性条目 Keyword Initial Value PRIORITY P 一个定义规则“显着性”值的整数。由“顺序”标志覆盖。 DURATION D 定义规则的“持续时间”值的长整数值。 TIMER T 定时器定义。请参阅“定时器和日历”。 ENABLED B 一个布尔值。 “真”使规则成为可能; “false”会禁用规则。 CALENDARS E 日历定义。请参阅“定时器和日历”。 NO-LOOP U 一个布尔值。 “真”禁止由于其结果所做的更改而循环的规则。 LOCK-ON-ACTIVE L 一个布尔值。 “true”禁止在同一个规则流或议程组中设置此标志的所有规则的额外激活。 AUTO-FOCUS F 一个布尔值。对于议程组中的规则而言“真实”会导致规则的激活从而自动将焦点集中到组中。 ACTIVATION-GROUP X 识别激活或XOR组的字符串。激活组中只有一个规则将被触发即第一个激活组将取消同一组内其他规则的任何激活。 AGENDA-GROUP G 一个标识一个议程组的字符串必须通过赋予其“焦点”来激活这是控制规则组之间流动的一种方式。 RULEFLOW-GROUP R 标识规则流组的字符串。 规则表 所有规则表都以一个包含“RuleTable”的单元格开始可选地在同一个单元格中跟随一个字符串。该字符串用作从该规则表派生的所有规则的名称的起始部分附加行号以区分。 这个自动命名可以通过使用NAME列来覆盖。定义此Rule Table规则的所有其他单元格位于该单元格的下方和右侧。 下一行定义了列的类型每列产生一部分条件或结果或者提供一些规则属性规则名称或注释。下表显示了哪些列标题可用;根据显示前一节中给出的规则属性条目的表格可以使用额外的列。请注意每个属性列最多只能使用一次。对于列标题请使用关键字或任何其他以这些表格的“初始”列中给出的字母开头的单词。 Table 3. 规则表中的列标题 Keyword Initial Value Usage NAME N 提供从该行生成的规则的名称。 默认值是根据RuleTable标签和行号之后的文本构造的。 最多只有一列 DESCRIPTION I 一个文本在生成的规则中产生一个注释。 最多只有一列 CONDITION C 代码片段和插值用于在条件中的模式中构建约束。 每个规则表至少有一个 ACTION A 代码片断和插值用于构建规则后果的操作。 每个规则表至少有一个 METADATA 代码片断和插值用于构建规则的元数据条目。 可选任意数量的列 给定一个标题为CONDITION的列连续行中的单元格产生一个条件元素。 CONDITION下面的第一个单元格中的文本发展成规则条件的模式下一行中的代码段成为约束条件。如果单元格与一个或多个邻居合并则形成具有多个约束的单个模式将所有约束合并到一个带括号的列表中并附加到该单元格中的文本。单元格可能会留空这意味着下一行中的代码片段必须单独生成有效的条件元素。 要包含没有约束的模式可以将模式写在另一个模式的文本前面。 模式可以写有或没有一个空的括号。 “from”子句可以附加到模式。 如果模式以“eval”结尾代码片段应该产生布尔表达式以包含在“eval”之后的一对括号中。 CONDITION下面的第二个单元格中的文本分两步处理。 这个单元格中的代码片段是通过插入列中更靠下的单元格中的值来修改的。如果要使用“”创建一个由下面的单元格的值组成的约束条件则仅字段选择器就足够了。任何其他比较运算符都必须被指定为代码片段中的最后一项并且下面单元格的值被附加。对于所有其他约束形式您必须标记位置以包含符号“$ param”的单元格的内容。通过在下面的单元格中使用符号“$ 1”“$ 2”等和逗号分隔值列表可以实现多重插入。 根据模式forall(delimiter{snippet}的文本的文本通过对每个单元格中的逗号分隔值列表的每个值重复snippet来展开在下面插入值代替符号$并且通过给定的delimiter加入这些扩展。请注意该构造可能被其他文本包围。 如果前一行中的单元格不是空的则将完成的代码片段添加到该单元格的条件元素中。一对括号是自动提供的如果将多个约束添加到合并单元格中的模式则会自动提供分隔逗号。 如果上面的单元格是空的插入的结果将按原样使用。 CONDITION下方的第三个单元格中的文本仅用于文档。它应该用来向读者指出专栏的目的。 从第四行开始非空白条目提供如上所述的插值数据。空白单元格导致省略该规则的条件元素或约束条件。 给出一个以行动为首的专栏连续行中的单元格产生一个行动陈述。 ACTION下面的第一个单元格中的文本是可选的。如果存在则将其解释为对象引用。 ACTION下面第二个单元格中的文本分两步处理。 这个单元格中的代码片段是通过插入列中更靠下的单元格中的值来修改的。对于单数插入用符号“$ param”标记包含单元格内容的位置。通过在下面的单元格中使用符号“$ 1”“$ 2”等和逗号分隔值列表可以实现多重插入。 没有内插的方法调用可以通过没有任何标记符号的文本来实现。在这种情况下请使用下面一行中的任何非空白条目来包含该语句。 这个构造也可以在这里找到。 2.如果第一个单元格不是空的其文本后面是一个句点第二个单元格中的文本和终止分号被串联在一起产生一个方法调用作为结果的一个动作语句添加。 如果上面的单元格是空的插入的结果将按原样使用。 ACTION下面的第三个单元格中的文本仅用于文档。它应该用来向读者指出专栏的目的。 从第四行开始非空白条目提供如上所述的插值数据。空白单元格导致省略此规则的操作语句。  在大多数情况下使用“$ 1”而不是“$ param”工作但如果替换文本包含逗号则会失败然后只插入第一个逗号前面的部分。 明智地使用这个“缩写”。 给定一个以METADATA开头的列连续行中的单元格将为生成的规则生成元数据注释。 METADATA下面第一个单元格中的文本被忽略。 如上所述METADATA下面的第二个单元格中的文本使用来自规则行单元格的值进行插值。元数据标记字符“”是自动添加的因此它不应该包含在这个单元格的文本中。 METADATA下面的第三个单元格中的文本仅用于文档。它应该用来向读者指出专栏的目的。 从第四行开始非空白条目提供如上所述的插值数据。空白单元格导致省略此规则的元数据注释。 例子 以下示例说明了各种插值。 例85.插值单元格数据 如果模板是“Foobar $ param”单元格是“42”那么结果是“Foobar 42”。 如果模板是“Foobar $ 1baz $ 2”而单元格包含“42,43”则结果将是“Foobar 42baz 43 。 模板forall{bar $}与一个包含42,43的单元格产生bar 42 bar 43。 下一个例子演示了定义模式类型的单元和下面的代码片段的共同作用。 br classApple-interchange-newline296/5000该电子表格部分显示了Person类型声明如何跨越2列因此这两个约束将以Personage …​type …​的形式出现。 由于只有字段名称存在于片段中因此意味着平等测试。 在下面的例子中使用了标志符号$ param。 这个列的结果是模式Personage “42”。 您可能已经注意到标记和运算符“”是多余的。 下一个例子说明了一个尾随的插入标记可以省略。 在这里从单元格中附加值是隐含的导致Person年龄42。 您可以提供绑定变量的定义如下例所示。 这里的结果是cCheesetype “stilton”。 请注意报价是自动提供的。 实际上任何东西都可以放在对象类型的行中。 除了绑定变量的定义之外它也可以是一个附加的模式可以直接插入。 下面显示了插入单个值的操作语句的简单构造。 ACTION标题下面的单元格留空。 使用这种风格任何事情都可以放在结果中而不仅仅是一个方法调用。 同样的技术也适用于CONDITION列。 下面是一个综合的例子展示了各种列标题的使用。 在列标题之下没有任何值是错误的如在NO-LOOP列中在这里属性不会被应用在任何规则中。 Figure 17. 关键字用于导入标题等的示例用法 最后这里是一个导入变量和函数的例子。 Figure 18. 功能关键字的使用示例等 同一单元格中的多个软件包名称必须用逗号分隔。此外类型和变量名称对必须用逗号分隔。但是函数必须按照出现在DRL文件中的方式编写。这应该与“RuleSet”关键字出现在同一列;它可以在所有规则行之上之间或之下。  It may be more convenient to use Import, Variables, Functions and Queries repeatedly rather than packing several definitions into a single cell. 创建和集成基于电子表格的决策表 使用基于电子表格的决策表的API位于drools-decisiontables模块中。实际上只有一个类可以看SpreadsheetCompiler。这个类将采取各种格式的电子表格并在DRL中生成规则然后可以以正常的方式使用。 SpreadsheetCompiler可以用来生成部分规则文件如果需要的话然后在事实之后将其组装成一个完整的规则包如果需要可以将规则的技术和非技术方面分开。 要开始可以使用示例电子表格作为基础。或者如果正在使用插件Rule Workbench IDE则向导可以从模板生成电子表格编辑它需要使用xls兼容的电子表格编辑器。 Figure 19. IDE中的向导 管理决策表中的业务规则 工作流程和协作 电子表格是完善的商业工具使用了25年以上。决策表适合密切IT和领域专家之间的合作同时使业务分析人员明确业务规则这是一个理想的分离关注点。 通常编写规则的整个过程提出一个新的决策表将是这样的 业务分析师采用模板决策表从存储库或从IT 决策表业务语言描述被输入到表格中 决策表规则行被输入大致 决策表交给技术资源他将业务语言描述映射到脚本当然这可能涉及软件开发如果是新的应用程序或数据模型 技术人员交回业务分析师的修改。 业务分析师可以根据需要继续编辑规则行移动列周围也很好等。 同时技术人员可以为规则开发测试用例与业务分析人员联系因为一旦系统运行这些测试用例可用于验证规则和规则更改。 使用电子表格功能 Excel等应用程序的功能可用于帮助将数据输入电子表格例如验证字段。存储在其他工作表中的列表可用于为单元格提供有效的值列表如下图所示。 一些应用程序提供了有限的能力来保存更改的历史记录但是建议使用另一种版本控制方法。当规则随时间发生变化时旧版本将被归档许多开源解决方案例如Subversion或Git。 规则模板 与决策表但不一定需要电子表格相关的是“规则模板”在drools-templates模块中。这些使用任何表格数据源作为规则数据的来源 - 填充模板以生成许多规则。这既可以用于更灵活的电子表格也可以用于现有数据库中的规则以开发模板为代价来生成规则。 使用规则模板数据与规则是分开的并且规则的哪一部分是数据驱动的没有限制。所以尽管你可以在决策表中做所有事情但你也可以做以下的事情 将数据存储在数据库或其他格式 有条件地根据数据中的值生成规则 为规则的任何部分使用数据例如条件运算符类名称属性名称 通过相同的数据运行不同的模板。例如显示了一个更经典的决策表但没有规则元数据的任何隐藏行所以电子表格只包含生成规则的原始数据。 Figure 20. 模板数据 请参阅上述电子表格示例下载中的ExampleCheese.xls。 如果这是一个常规决策表那么在行1之前以及包含规则元数据的行1和行2之间将存在隐藏行。使用规则模板数据与规则完全分开。这有两个方便的后果 - 您可以将多个规则模板应用于相同的数据并且您的数据根本不依赖于您的规则。那么模板是什么样的 1 template header 2 age 3 type 4 log 5 6 package org.drools.examples.templates; 7 8 global java.util.List list; 9 10 template cheesefans 11 12 rule Cheese fans_{row.rowNumber} 13 when 14 Person(age {age}) 15 Cheese(type {type}) 16 then 17 list.add({log}); 18 end 19 20 end template 上述程序清单的注释 第1行所有规则模板以template header开始。 第2-4行在标题之后是按照它们在数据中出现的顺序排列的列表。在这种情况下我们称第一列时间第二种类型和第三个日志。 第5行空行表示列定义的结束。 第6-9行标准规则标题文本。这是DRL的标准规则将出现在生成的DRL的顶部。将package语句和任何导入以及全局和函数定义放入本节。 第10行关键字模板表示规则模板的开始。模板文件中可以有多个模板但每个模板都应该有唯一的名称。 第11-18行规则模板 - 详见下文。 第20行关键字结束模板表示模板的结尾。 规则模板依靠MVEL使用语法 {token_name}进行替换。目前有一个内置的表达式 {row.rowNumber}它为每一行数据提供唯一的编号并使您能够生成唯一的规则名称。对于每一行数据都会生成一个规则用数据中的值代替模板中的令牌。 规则模板必须包含在扩展名为.drt的文件中并且在定义kmodule.xml文件中的kbase时与相应的决策表相关联如下例所示 ?xml version1.0 encodingUTF-8? kmodule xmlnshttp://drools.org/xsd/kmodulekbase nameTemplatesKB packagesorg.drools.examples.templates ruleTemplate dtableorg/drools/examples/templates/ExampleCheese.xls templateorg/drools/examples/templates/Cheese.drt row2 col2/ ksession nameTemplatesKS/ /kbase /kmodule 通过上面的示例数据将生成以下规则文件 package org.drools.examples.templates;global java.util.List list;rule Cheese fans_1 whenPerson(age 42) Cheese(type stilton) then list.add(Old man stilton); end rule Cheese fans_2 when Person(age 21) Cheese(type cheddar) then list.add(Young man cheddar); end 此时名为“TemplatesKS”的KieSession包含从模板生成的规则可以简单地从KieContainer创建并用作其他KieSession。 KieSession ksession kc.newKieSession( TemplatesKS );// now create some test data ksession.insert( new Cheese( stilton, 42 ) ); ksession.insert( new Person( michael, stilton, 42 ) ); final ListString list new ArrayListString(); ksession.setGlobal( list, list ); ksession.fireAllRules(); 记录日志 照亮作为规则引擎的黑盒子的一种方法是玩日志级别。 一切都记录到SLF4J这是一个简单的日志记录门面可以将任何日志委托给LogbackApache Commons LoggingLog4j或java.util.logging。将日志适配器的依赖关系添加到您选择的日志框架中。如果你还没有使用任何日志框架你可以通过添加这个Maven依赖项来使用Logback dependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.x/version/dependency  如果您正在开发超轻型环境请使用slf4j-nop或slf4j-simple。 在包org.drools上配置日志记录级别。例如 在Logback中将其配置到您的logback.xml文件中 configurationlogger nameorg.drools leveldebug/...configuration 在Log4J中将其配置到您的log4j.xml文件中 log4j:configuration xmlns:log4jhttp://jakarta.apache.org/log4j/category nameorg.droolspriority valuedebug //category.../log4j:configuration 转载于:https://www.cnblogs.com/prpl/p/7875328.html
http://www.yutouwan.com/news/375641/

相关文章:

  • wordpress编辑器添加视频seo排名优化软件免费
  • 自己的网站中商城怎么做手机上做网站
  • 手机上有趣的网站wordpress主题点赞
  • 加强公司门户网站建设方案网站商城建设员招聘信息
  • 深圳网站开发公司淘宝联盟推广网站怎么做
  • 过年做啥网站能致富德阳定制建站网站建设制作
  • 如何查看网站是用什么模板做的临沂建设网站
  • 网站底部备案图标摄影婚纱官网
  • 新余 网站建设网站建设广告合同需要交印花税吗
  • 外包网络推广公司推广网站什么网站可以自己做配图
  • 番禺网站 建设信科网络wordpress安装好怎么设置密码
  • 公司做网站计入那个科目宝山苏州网站建设
  • 全网vip影视自助建站系统wordpress 主题页脚
  • wordpress chrome插件枣庄seo外包
  • 做网站软件排名金融服务网站建设
  • google 网站突然一条收录也没有浙江建设继续教育学院网站
  • 上海建设网站费用网站建设用哪个好
  • c2c电子商务网站用到的技术连云港企业做网站
  • 三亚市住房和城乡建设厅网站南昌seo网站开发
  • 顺德网站建设公司价位店招在线制作免费
  • 嘉兴提高网站排名官网下载软件
  • 网页设计师主要是做什么网站开发使用api对seo
  • 中国建设的网站介绍小说的网站模板下载
  • 桐庐做网站两学一做 网站源码
  • 个人网站怎么做代码国外php网站源码
  • 苏州网站建设制作服务商图片制作在线生成器免费版
  • 重庆做网站建设公司上海建设厅网站首页
  • 阿里网站如何做接入鄂州网站建设推广报价
  • 网站开发商城市场调研分析报告
  • 福州网站制作公司个人网站命名