Person p=new Person("张三",10);条件元素 forall
Person ps=new Person("李四",50);
rule "All English buses are red"
when
forall( $bus : Bus( type == 'english')
Bus( this == $bus, color = 'red' ) )
then
# all english buses are red
end
rule "All Buses are Red"
when
forall( Bus( color == 'red' ) )
then
# all asserted Bus facts are red
end
另外一个例子,显示了 forall 内部的多个模式:
rule "all employees have health and dental care programs"
when
forall( $emp : Employee()
HealthCare( employee == $emp )
DentalCare( employee == $emp )
)
then
# all employees have health and dental care
end
rule "not all employees have health and dental care"
when
not ( forall( $emp : Employee()
HealthCare( employee == $emp )
DentalCare( employee == $emp ) )
)
then
# not all employees have health and dental care
end
rule "validate zipcode"
when
Person( $personAddress : address )
Address( zipcode == "23920W") from $personAddress
then
# zip code is ok
end
rule "validate zipcode"
when
$p : Person( )
$a : Address( zipcode == "23920W") from $p.address
then
# zip code is ok
end
rule "apply 10% discount to all items over US$ 100,00 in an order"
when
$order : Order()
$item : OrderItem( value > 100 ) from $order.items
then
# apply discount to $item
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person( )
$a : Address( state == "NC") from $p.address
then
modify ($p) {} #Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person( )
$a : Address( city == "Raleigh") from $p.address
then
modify ($p) {} #Apply discount to person in a modify block
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person(address.state == "NC" )
then
modify ($p) {} #Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person(address.city == "Raleigh" )
then
modify ($p) {} #Apply discount to person in a modify block
end
rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
$p : Person($addresses : addresses)
exists (Address(state == "NC") from $addresses)
then
modify ($p) {} #Assign person to sales region 1 in a modify block
end
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person($addresses : addresses)
exists (Address(city == "Raleigh") from $addresses)
then
modify ($p) {} #Apply discount to person in a modify block
end
import java.util.ArrayList
rule "Raise priority if system has more than 3 pending alarms"
when
$system : System()
$alarms : ArrayList( size >= 3 )
from collect( Alarm( system == $system, status == 'pending' ) )
then
# Raise priority, because system $system has
# 3 or more alarms pending. The pending alarms
# are $alarms.
end
import java.util.LinkedList;
rule "Send a message to all mothers"
when
$town : Town( name == 'Paris' )
$mothers : LinkedList()
from collect( Person( gender == 'F', children > 0 ) from $town.getPeople() )
then
# send a message to all mothers
end
Accumulate 功能更容易测试和重用
Accumulate 还支持多个不同的语法。首选的语法是顶级积累,如上所述波纹管,但所有其他语法支持向后兼容。
accumulate(
;
[;
] )
例如,一个规则来计算最小,最大,使用
Accumulate
rule "取对象中的最大值,和最小值"
dialect "mvel"
when
accumulate(Person($value:age),
$min:min($value),
$max:max($value);
$max<=5
)
then
System.out.println($min+">>>>>>>>>>>"+$max);
end
Drools附带几个内置的accumulate功能,包括:
average 平均值
min 最小值
max 最大值
count 统计
sum 求和
collectList 返回List
collectSet 返回HastSet
rule "sun求和后减1"
dialect "mvel"
when
//$n:Number() from
accumulate(Person($value:age),
$sum:sum($value-1)
)
then
System.out.println("求和减1>>>>>>>>>>>>"+$sum);
end
AccumulateFunction
import accumulate com.drools.TestAccunmulateneeded getResult
from accumulate(
,
init(
),
action(
),
reverse(
),
result(
) )
下面我们对这些语法进行一个说明:
: 返回值类型,在 返回值的类型再一次进行匹配,如果匹配不成功则返回false。
rule "测试accumulatefrom用法1"
dialect "mvel"
when
$total : String() from
accumulate(Person($value:dous),
init( Double total = 0.1; Person p = new Person();),
action( total += $value; ),
result( p )
)
then
System.out.println($total+"accumulate from 用法 求和");
end
@Test
public void 测试accumulatefrom用法reverse() throws Exception {
Resource dis = ResourceFactory.newClassPathResource("rules/testdrl/accumulatefreverse.drl", TestTemplate01.class);
KieHelper helper = new KieHelper();
helper.addResource(dis, ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
for(int i=1;i<6;i++){
Person person=new Person();
person.setDous(1.0+i);
person.setAge(i);
ksession.insert(person);
}
int i = ksession.fireAllRules(new RuleNameStartsWithAgendaFilter("测试accumulatef"));
System.out.println( " " + i + "次");
ksession.dispose();
}
DRL文件的使用:
/*rule "测试accumulatefrom3用法reverse2"
dialect "mvel"
when
$ps:Person(dous>=3)
then
$ps.setDous(1.2);
update($ps);
System.out.println($ps.dous);
end*/
//为什么会将上面这一规则注释,因为根据调用方法,此规则会先执行,会影响到后面的规则
rule "测试accumulatefrom用法reverse"
dialect "mvel"
when
$total : Double() from
accumulate(Person(dous>=3,$age:age),
init(Double totls = 0.0),
action(totls+=$age;System.out.println(totls+">>>>>>>>>");),
reverse( totls-=$age; System.out.println(totls+"<<<<<<<<");),//,
result( totls )
)
then
System.out.println($total+"+++++++++++");//+$s.count+$s.name);
end
rule "测试accumulatefrom3用法reverse"
dialect "mvel"
when
$ps:Person(dous>=3)
then
$ps.setDous(1.2);
update($ps);
System.out.println($ps.dous);
end
accumulate
中,得出几个结论:
rule "取对象中的最大值,和最小值"
dialect "mvel"
when
accumulate(Person($value:age),
$min:min($value),
$max:max($value);
$max<=5
)
then
System.out.println($min+">>>>>>>>>>>"+$max);
end
4、min()写法,前面没有加任何的变量引用说明,当然也不可能在函数的结束符";"后面再加条件约束,并且,想要使用函数中返回的结果,在这种没有引用变量的前提下,则必须要引用from 关键字, 但from关键字有一个问题,就是返回的结果,必须是一个(表示说源模式结束符后面只能有一个函数),且使用函数时,不能有变量引用,这样才能正常使用from。
rule "min的使用"
dialect "mvel"
when
$n:Number()
accumulate(Person($value:age);
min($value)
)
then
System.out.println("min的使用");
end
5、根据上面的说法 使用 accumulate 语法上如果source pattern 结束符后面函数的结果有变量,则不能使用from,且使用from 返回结果必须是一个。
package com.drools;
import org.kie.api.runtime.rule.AccumulateFunction;
import java.io.*;
/**
* Created by kangz on 2016/9/6.
*/
public class TestAccunmulateneeded implements AccumulateFunction{
public static class Factorial implements Externalizable {
public Factorial(){}
public double total = 1;
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeDouble(total);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
total=in.readDouble();
}
}
@Override
public Class> getResultType() {
return Number.class;
}
@Override
public Serializable createContext() {
return new Factorial();
}
@Override
public void init(Serializable serializable) throws Exception {
Factorial factorial= (Factorial) serializable;
factorial.total=1;
}
@Override
public void accumulate(Serializable serializable, Object o) {
Factorial factorial= (Factorial) serializable;
factorial.total *= ((Number)o).doubleValue();
}
@Override
public void reverse(Serializable serializable, Object o) throws Exception {
}
@Override
public Object getResult(Serializable serializable) throws Exception {
Factorial factorial= (Factorial) serializable;
Double d =new Double(((Factorial) serializable).total ==1?1:((Factorial) serializable).total);
return d;
}
@Override
public boolean supportsReverse() {
return true;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
import accumulate com.drools.TestAccunmulateneeded 自定义的名称
通过方面的方法,我们就能使用我们自定义的函数了,但要注意的是,使用 accumulate时,返回值上面有说过,这里不多说了。用法和sum,min等等 是一样的,但要注意的是,如果我们自定的名称是sum ,min等等,调用用的也是自带的方法,不会对原方法进行重写,那具体的用法是这样的:
import accumulate com.drools.TestAccunmulateneeded factorial
rule "自定义函数阶乘"
dialect "mvel"
when
//$n:Number() from
accumulate(Person($value:age !=null ) ,
$factorial:factorial($value)
)
then
System.out.println("自定义函数>>>>>>>>>>>>"+$factorial);
end
下面是小编的微信转帐二维码,小编再次谢谢读者的支持,小编会更努力的
----请看下方↓↓↓↓↓↓↓
百度搜索 Drools从入门到精通:可下载开源全套Drools教程
深度Drools教程不段更新中:
更多Drools实战陆续发布中………
扫描下方二维码关注公众号 ↓↓↓↓↓↓↓↓↓↓