1. Background
Here we will introduce the writing method of the drools
and the then
part, as well as some built-in methods, such as insert/delete/modify
and so on. At the same time, it also introduces the inheritance of rule
when
, and the implementation of if else if
and other operations in ---102448e5516b1e46e0773578e44a12e7---.
2. Supported methods
drools provides some built-in methods that modify the value of the Fact
object in drools 工作内存
. This will cause the pattern matching to be repeated.
2.1 insert Insert objects into working memory
insert
is to insert the object into the working memory, which will cause the pattern matching of the rules to be repeated. At the same time, when the rule is not satisfied, it will not be automatically deleted.
2.1.1 Requirements
When a fire occurs Fire
, insert a Alarm
object into the working memory, after the alarm occurs, delete the Fire
object in the working memory, and then check Alarm
whether the object still exists.
2.1.2 drl file writing
package rules
import com.huan.drools.insertmethod.Fire
import com.huan.drools.insertmethod.Alarm
rule "insert_发生火灾时,往工作内存中插入告警对象"
when
$fire: Fire()
then
System.out.println("1、发生火灾时,往工作内存中插入告警对象");
insert(new Alarm($fire));
end
rule "insert_当规则内存中存在告警对象,进行告警,然后删除火灾对象"
when
$fire: Fire()
$alarm: Alarm( fire == $fire )
then
System.out.println("2、进行告警,然后删除对应的火灾对象");
end
rule "insert_检测告警对象是否还是存在-01"
when
Alarm()
then
System.out.println("3、insert 插入的告警对象还存在");
// 删除工作内存中的Fire对象
delete($fire);
end
rule "insert_检测告警对象不存在"
when
not Alarm()
then
System.out.println("3、insert 插入的告警对象不存在");
end
Here is insert
for insertion
2.1.3 Part of java code writing
// 将火灾对象插入到工作内存中
kieSession.insert(new Fire());
// 只触发规则名称以 insert_ 开头的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insert_"));
2.1.4 Running Results
1、发生火灾时,往工作内存中插入告警对象
2、进行告警,然后删除对应的火灾对象
3、insert 插入的告警对象还存在
2.1.5 Conclusion
-
insert
can insertFact
objects into working memory. -
insert
After the method is called, the pattern will be re-matched, resulting in the re-execution of the rules that were not executed before. -
insert
The object inserted into the working memory by the method will not be deleted automatically when the rule is not established, it needs to be deleted manually, pay attention to the difference frominsertLogical
2.2 insertLogical inserts objects into working memory
insert
is to insert the object into the working memory, which will cause the pattern matching of the rules to be repeated. At the same time, when the rule is not satisfied, it will be automatically deleted.
2.2.1 Requirements
When a fire occurs Fire
, insert a Alarm
object into the working memory, after the alarm occurs, delete the Fire
object in the working memory, and then check Alarm
whether the object still exists.
2.2.2 drl file writing
package rules
import com.huan.drools.Fire
import com.huan.drools.Alarm
rule "insertLogical_发生火灾时,往工作内存中插入告警对象"
when
$fire: Fire()
then
System.out.println("1、发生火灾时,往工作内存中插入告警对象");
insertLogical(new Alarm($fire));
end
rule "insertLogical_当规则内存中存在告警对象,进行告警,然后删除火灾对象"
when
$fire: Fire()
$alarm: Alarm( fire == $fire )
then
System.out.println("2、进行告警,然后删除对应的火灾对象");
delete($fire);
end
rule "insertLogical_检测告警对象是否还是存在-01"
when
Alarm()
then
System.out.println("3、insertLogical 插入的告警对象还存在");
end
rule "insertLogical_检测告警对象不存在"
when
not Alarm()
then
System.out.println("3、insertLogical 插入的告警对象不存在");
end
Used here insertLogical
insert
2.2.3 Part of java code writing
kieSession.insert(new Fire());
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insertLogical_"));
2.2.4 Running Results
1、发生火灾时,往工作内存中插入告警对象
2、进行告警,然后删除对应的火灾对象
3、insertLogical 插入的告警对象不存在
2.2.5 Conclusion
-
insertLogical
can insertFact
object into working memory. -
insertLogical
After the method is called, it will cause the pattern to be re-matched, resulting in the re-execution of the rules that were not executed before. -
insertLogical
The object inserted into the working memory by the method will be automatically deleted when the rule is not established. Note the difference betweeninsert
2.3, update updates objects in working memory
update:
Use this to specify which fields and entire related Facts to update, and notify the Drools engine of the changes. After the Fact has changed, you must call update before changing another fact that might be affected by the updated value. 为避免此添加步骤,请改用 modify 方法。
2.3.1 Requirements
Rule 1: When there is a fire object Fire
in the working memory, and the name is empty, the rule is triggered, and the name of the fire is set to 大火灾
.
Rule 2: When the fire has a name, output the name of the fire
2.3.2 drl file writing
package rules
import com.huan.drools.Fire
import com.huan.drools.Alarm
rule "update_当存在火灾对象时,设置一个火灾的名字"
when
$fire: Fire(name == null)
then
System.out.println("1、设置火灾名字");
$fire.setName("大火灾");
update($fire)
end
rule "update_当火灾对象存在名字时触发"
when
$fire: Fire(name != null)
then
System.out.println("2、火灾对象的名字为: " + $fire.getName());
end
2.3.3 Part of java file writing
kieSession.insert(new Fire());
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("update_"));
2.3.4 Running Results
1、设置火灾名字
2、火灾对象的名字为: 大火灾
2.3.4 Conclusion
-
update
will cause a rematch of the pattern. -
update
will modify the value in the working object memory.
2.4, modify update objects in working memory
modify:
Use this to specify the fields to be modified for the Fact object and notify the Drools engine of the changes. This method provides a structured fact update method. It combines update operations with setter calls to change object fields.
2.4.1 Requirements
Rule 1: When there is a fire object Fire
in the working memory, and the name is empty, the rule is triggered, and the name of the fire is set to 大火灾
.
Rule 2: When the fire has a name, output the name of the fire
2.4.2 drl file writing
package rules
import com.huan.drools.Fire
import com.huan.drools.Alarm
rule "modify_当存在火灾对象时,设置一个火灾的名字"
when
$fire: Fire(name == null)
then
System.out.println("1、设置火灾名字");
modify($fire){
setName("大火灾")
}
end
rule "modify_当火灾对象存在名字时触发"
when
$fire: Fire(name != null)
then
System.out.println("2、火灾对象的名字为: " + $fire.getName());
end
2.4.3 Part of java file writing
kieSession.insert(new Fire());
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("modify_"));
2.4.4 Running Results
1、设置火灾名字
2、火灾对象的名字为: 大火灾
2.4.5 Conclusion
-
modify
will cause the pattern to be rematched. -
modify
will modify the value in the working object memory. - In general, use
modify
, do not useupdate
.
2.5 delete deletes objects in working memory
Usage: delete(<object>)
retract
is also the same as delete
, but delete
is recommended.
3. Simple use of drools variables
package rules
rule "drools_变量的使用"
when
eval(true)
then
System.out.println("Match激活的当前触发规则: " + 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"); );
// System.out.println("获取查询结果:" + drools.getKieRuntime().getQueryResults());
end
4. Inheritance of rules
4.1 Requirements
Rule 1: If the age ( age
--- ) of the user ( customer
) is greater than 60 years old, the discount will be 0.9
.
Rule 2: On the basis of rule 1, if the user has a car ( car
), he can park for free ( freeParking
).
4.2 drl file writing
package rules
import com.huan.drools.Customer
import com.huan.drools.Car
rule "rule_extends_规则一"
when
$c: Customer(age > 60)
then
modify($c){
setDiscount(0.9)
}
System.out.println("触发规则一:用户年龄>60岁,打0.9折");
end
// 规则二继承规则一的条件
rule "rule_extends_规则二" extends "rule_extends_规则一"
when
$car: Car()
then
modify($car){
setFreeParking(true)
}
System.out.println("触发规则二:用户有车,免费停车");
end
Here rule_extends_规则二
inherits rule_extends_规则一
, so the condition of rule 1 is also inherited.
4.3 Part of the java code
Car car = new Car();
Customer customer = new Customer();
customer.setAge(65);
kieSession.insert(customer);
kieSession.insert(car);
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_extends_"));
The customer has a car and is 65 years old and satisfies Rule 1 and Rule 2 above
4.4 Running Results
触发规则一:用户年龄>60岁,打0.9折
触发规则二:用户有车,免费停车
4.5 Conclusion
It can be seen that using the rule
extends
keyword on ---bf635358351438a720b9a2b5dcc04243--- can implement rule inheritance.
5. Use the do[...] syntax to rewrite the above inheritance example
5.1 Requirements
As long as the user is over 60 years old, they can directly get a 0.9% discount, and if there is a car, they can park for free.
5.2 drl file writing
package rules
import com.huan.drools.Customer
import com.huan.drools.Car
rule "命名结果_rule"
when
$c: Customer(age > 60)
do[giveDiscount] // 当上方的条件成立时执行 then [giveDiscount]
$car: Car() // 此条件成立时,执行默认的 then
then
modify($car){
setFreeParking(true)
};
System.out.println("用户有车,免费停车");
then [giveDiscount]
modify($c){
setDiscount(0.9)
};
System.out.println("用户年龄>60岁,打0.9折");
end
解释:
see the gaze in the rules file above
5.3 Part of java code writing
Car car = new Car();
Customer customer = new Customer();
customer.setAge(65);
kieSession.insert(customer);
kieSession.insert(car);
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("命名结果_"));
5.4 Running Results
用户年龄>60岁,打0.9折
用户有车,免费停车
also fulfilled the demand
5.5 Conclusion
By using when
do[名字]
and then then
then 名字
can also be achieved.
6. Realize the effect of if else if
6.1 Requirements
Complete similar if else if else
effect. See the various execution results below .
6.2 Rules file
rule "if else-if"
when
$customer: Customer(age > 60) // 规则内存中存在Customer对象,并且age>60
if($customer.getLevel() == 1) do[level1] // 用户的级别是1,执行then[level1],然后继续执行下方的条件
else if ($customer.getLevel() == 2) break[level2] // 用户的级别是2,执行then[level2],不在执行下方的条件
else do[levelOther] // 其他的level级别,执行then[levelOther],然后在执行下方的条件
Car()
then
System.out.println("我执行了");
then[level1]
System.out.println("level1");
then[level2]
System.out.println("level2");
then[levelOther]
System.out.println("levelOther");
end
6.3 Execution result graph
6.4 Various execution results - that is, the explanation of the above figure
1. The Customer
of age
is smaller than 60
.
输出:
No output.
2、 Customer
的age
60
level=1
,没有Car
。
输出:
level1
3、 Customer
的age
60
level=1
,有Car
。
输出:
level1 I executed
4、 Customer
的age
60
level=2
,没有Car
。
输出:
level2
5、 Customer
的age
60
level=2
,有Car
。
输出:
level2
6、 Customer
的age
60
level=3
,没有Car
。
输出:
levelOther
7、 Customer
的age
60
level=3
,有Car
。
输出:
levelOther I executed
6.5 What is the difference between do and break
do
: After execution, it will continue to judge the following execution conditions. ( 即还会执行后面的Car判断,根据是否有Car获取不同的结果
)
break
: After execution, the following execution conditions will not be judged. ( 即忽略了后面的Car判断,rule执行完了
)
7. Complete code
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-then
8. Reference documents
1. https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#drl-rules-THEN-con_drl-rules
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。