指定规则名的方式
java代码
@Test
public void testjblx() throws Exception {
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/testjblx.drl", TestTemplate01.class);
ObjectDataCompiler converter = new ObjectDataCompiler();
Collection<TestPersonSet> cfl = new ArrayList<TestPersonSet>();
KieHelper helper = new KieHelper();
helper.addResource(dis,ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
FactHandle f = ksession.insert(list);
ksession.fireAllRules(new RuleNameEndsWithAgendaFilter("bbb"));
ksession.delete(f);
FactHandle fs = ksession.insert(list);
int i = ksession.fireAllRules(new RuleNameEndsWithAgendaFilter("aaa")); // 指定 具体规则以bbb结尾的规则
System.out.println( " " + i + "次");
ksession.dispose();
}
Drl代码
rule aaa
when
$list:ArrayList();
$listint:Integer(intValue > 485) from $list
then
System.out.println($listint.longValue());
end
rule bbb
when
$list:ArrayList();
$listchar:String(toString =="张400") from $list
then
System.out.println($listchar.toString());
end
简单说明一下上面的代码:上面的代码中包含了三个概念性的东西。 第一:指定规则名执行、第二:指定规则名在同一方法中的多次调用、第三:集合存放常量时的from用法。
我们先说指定规则名:
其实指定规则名比较简单一些:fireAllRules中实例化一个RuleNameEndsWithAgendaFilter类,此类有一构造函数,可传规则名,和是否执行的boolean类型。
指定规则名同一方法中的多次调用,则需要FactHandle f = ksession.insert(list); 中的FactHandle 因为在规则执行后 之前的实例对象已经存在,想要再执行 则必须将之前insert的FactHandle 删除,即
ksession.delete(f);,然后再次将想要执行的规则执行,如果想要将再次使用fack对象,则再insert一次即可。
集合存放常量时的from用法,其实也是比较简单,即,from元素之后放的对象中必须要包含from元素之前的对象,之前有说过,from 有点类似 父子级包含关系。至于常量的比较,则是由包装类进行取值比较。
上面的说明,可能满足不了太多的需要,毕竟有的时候会用到kmodule.xml 或者是spring的方法去做,在同一个packages中可能存在很多的规则文件 所以有一种叫做 自定义规则批量执行(本人是这样理解的,可能与官方说法不太一样)方式,经过与同事的研究成果,下面我就简单的说明一下 批量执行指定的规则名。
首先,我们要重写一个方法,自定义一个类CustomAgendaFilter 并实现AgendaFilter接口(6.4版本的使用) 好,让我们看一下具体的代码
package com.drools.web.jars;
import org.kie.api.runtime.rule.AgendaFilter;
import org.kie.api.runtime.rule.Match;
import java.util.Set;
/**
* Created by kangz on 2016/9/7.
*/
public class CustomAgendaFilter implements AgendaFilter {
private final Set<String> ruleNamesThatAreAllowedToFire;//传入的rule name
public CustomAgendaFilter(Set<String> ruleNamesThatAreAllowedToFire) {
this.ruleNamesThatAreAllowedToFire = ruleNamesThatAreAllowedToFire;
}
@Override
public boolean accept(Match match) {
return ruleNamesThatAreAllowedToFire.contains(match.getRule().getName());
}
}
实现代码:
@Test
public void namesRules(){
//KieSession kieSession= newKisessions();
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/StatelessRulesName.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession kieSessionieSession=helper.build().newKieSession();
Set set=new HashSet();
set.add("name的使用1");
set.add("name的使用3");
set.add("name的使用5");
kieSessionieSession.fireAllRules(new CustomAgendaFilter(set));
}
DRL文件:
rule "name的使用1"
dialect "mvel"
when
then
System.out.println("name的使用1正在使用");
end
rule "name的使用2"
dialect "mvel"
when
forall(p:Person(name=="张三") Person(this==p,age==10));
then
System.out.println("name的使用2正在使用");
end
rule "name的使用3"
when
forall(p:Person(name=="张三") Person(this==p,age==10));
then
System.out.println("name的使用3正在使用");
end
rule "name的使用4"
dialect "mvel"
when
forall(p:Person(name=="张三") Person(this==p,age==10));
then
System.out.println("name的使用4正在使用");
end
rule "name的使用5"
dialect "mvel"
when
forall(p:Person(name=="张三") Person(this==p,age==10));
then
System.out.println("name的使用5正在使用");
end
通过上面的代码,我们有一个清楚的了解,就是我们可以更灵活的去使用调用指定的规则名执行规则。
上面的说明只是冰山一角,下面我会直接通过代码来说明指定规则名的强大功能。
规则名全匹配
过滤器激活基于精确匹配规则的名称 源码中说明
@Test
public void newRuleNameEqualsAgendaFilter(){
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/StatelessRulesName.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
int i =ksession.fireAllRules(new RuleNameEqualsAgendaFilter("name的使用6"));//根据规则名精确执行所有匹配的规则
System.out.println("共执行了 "+i);
}
指定以XXX开头的写法
根据指定的规则名称前缀过滤器激活。源码中说明
@Test
public void newRuleNameStartsWithAgendaFilter(){
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/StatelessRulesName.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
int i =ksession.fireAllRules(new RuleNameStartsWithAgendaFilter("name"));//根据规则名开头执行所有匹配的规则
System.out.println("共执行了 "+i);
}
指定以XXX结尾的写法
根据指定的规则名称后缀过滤器激活。
@Test
public void newRuleNameEndsWithAgendaFilter(){
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/StatelessRulesName.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
int i =ksession.fireAllRules(new RuleNameEndsWithAgendaFilter("的使用6"));//根据规则结尾执行所有匹配的规则
System.out.println("共执行了 "+i);
}
指定正则匹配的形式,听起来就很牛叉。
根据指定的正则表达式过滤器激活。
@Test
public void namesRulesregular(){
//KieSession kieSession= newKisessions();
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/StatelessRulesName.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession kieSessionieSession=helper.build().newKieSession();
int i= kieSessionieSession.fireAllRules(new RuleNameMatchesAgendaFilter("\\w{0,5}[\\u4e00-\\u9fa5]{0,10}\\d"));
System.out.println("共执行了 "+i);
}
// 其实我们可以从
accept方法中可以看出来,还有两个方法我没有说。
这两种方式会有后面的章节中有所说明。
返回来我们说一下fireAllRules里的一些其他,这个方法其实是一个重载方法。里面有以下几种类型:
第一种:
int
fireAllRules
() 不多说了,执行所有满足条件的规则
第二种:
int
fireAllRules
(
int
max
)
执行规则的最大数量,简单的说,执行多少条规则
第三种:
int
fireAllRules
(
AgendaFilter
agendaFilter
)
指定规则名的方式
第一种:
int
fireAllRules
(
AgendaFilter
agendaFilter
, int
max
)
;指定规则名,并执行多少条
下面是小编的微信转帐二维码,小编再次谢谢读者的支持,小编会更努力的
----请看下方↓↓↓↓↓↓↓
百度搜索 Drools从入门到精通:可下载开源全套Drools教程
深度Drools教程不段更新中:
更多Drools实战陆续发布中………
扫描下方二维码关注公众号 ↓↓↓↓↓↓↓↓↓↓