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

  1. insert can insert Fact objects into working memory.
  2. 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.
  3. 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 from insertLogical

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

  1. insertLogical can insert Fact object into working memory.
  2. 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.
  3. insertLogical The object inserted into the working memory by the method will be automatically deleted when the rule is not established. Note the difference between insert

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

  1. update will cause a rematch of the pattern.
  2. 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

  1. modify will cause the pattern to be rematched.
  2. modify will modify the value in the working object memory.
  3. In general, use modify , do not use update .

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、 Customerage 60 level=1 ,没有Car
输出: level1
3、 Customerage 60 level=1 ,有Car
输出: level1 I executed
4、 Customerage 60 level=2 ,没有Car
输出: level2
5、 Customerage 60 level=2 ,有Car
输出: level2
6、 Customerage 60 level=3 ,没有Car
输出: levelOther
7、 Customerage 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


huan1993
218 声望34 粉丝

java工程师