這篇文章主要介紹“drools中then部分怎么寫”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“drools中then部分怎么寫”文章能幫助大家解決問題。
此處介紹一下drools
中then
部分的寫法,以及一些內置的方法,比如insert/delete/modify
等等。同時也介紹一下rule
的繼承,和在when
中實現if else if
等操作。
drools提供了一些內置的方法,這些方法會修改drools的工作內存
中Fact
對象的值。從而會導致重新進行模式匹配。
insert
是向工作內存中插入對象,同時會導致重新進行規則的模式匹配。同時當規則不滿足時,不會自動刪除。
當發生火災Fire
時,向工作內存中插入一個Alarm
對象,告警發生后,刪除工作內存中的Fire
對象,然后檢測Alarm
對象是否還存在。
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
此處使用的是 insert
進行插入
// 將火災對象插入到工作內存中 kieSession.insert(new Fire()); // 只觸發規則名稱以 insert_ 開頭的規則 kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insert_"));
1、發生火災時,往工作內存中插入告警對象
2、進行告警,然后刪除對應的火災對象
3、insert 插入的告警對象還存在
insert可以向工作內存中插入Fact對象。
insert方法調用后,會導致模式的重新匹配,導致之前不會執行的規則,重新執行。
insert方法插入到工作內存的對象,在規則不成立時,不會自動刪除,需要手動刪除,注意和insertLogical的區別
insert
是向工作內存中插入對象,同時會導致重新進行規則的模式匹配。同時當規則不滿足時,會自動刪除。
當發生火災Fire
時,向工作內存中插入一個Alarm
對象,告警發生后,刪除工作內存中的Fire
對象,然后檢測Alarm
對象是否還存在。
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
此處使用的是insertLogical
插入
kieSession.insert(new Fire()); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("insertLogical_"));
1、發生火災時,往工作內存中插入告警對象
2、進行告警,然后刪除對應的火災對象
3、insertLogical 插入的告警對象不存在
insertLogical可以向工作內存中插入Fact對象。
insertLogical方法調用后,會導致模式的重新匹配,導致之前不會執行的規則,重新執行。
insertLogical方法插入到工作內存的對象,在規則不成立時,會自動刪除注意和insert的區別
update:
使用它來指定要更新的字段和整個相關Fact,并將更改通知 Drools 引擎。 Fact發生更改后,您必須在更改可能受更新值影響的另一個事實之前調用 update。 為避免此添加步驟,請改用 modify 方法。
規則一: 當工作內存中存在火災對象Fire
,并且名字name為空時觸發規則,同時在設置火災的名字為大火災
。
規則二: 當火災存在名字時,輸出火災名字
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
kieSession.insert(new Fire()); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("update_"));
1、設置火災名字
2、火災對象的名字為: 大火災
update
會導致模式的重新匹配。
update
會修改工作對象內存中的值。
modify:
使用它來指定要為Fact對象修改的字段并將更改通知 Drools 引擎。 此方法提供了一種結構化的事實更新方法。 它將更新操作與 setter 調用相結合以更改對象字段。
規則一: 當工作內存中存在火災對象Fire
,并且名字name為空時觸發規則,同時在設置火災的名字為大火災
。
規則二: 當火災存在名字時,輸出火災名字
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
kieSession.insert(new Fire()); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("modify_"));
1、設置火災名字
2、火災對象的名字為: 大火災
modify
會導致模式的重新匹配。
modify
會修改工作對象內存中的值。一般情況下使用modify
,不要使用update
。
用法:delete(<object>)
retract
也是和delete
一樣的效果,但是推薦使用delete
。
package rules rule "drools_變量的使用" wh 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
規則一: 如果用戶(customer
)的年齡(age
)大于60歲,則打0.9
折。
規則二: 在規則一的基礎上,如果用戶有車(car
),則可以免費停車(freeParking
)。
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
此處rule_extends_規則二
繼承了rule_extends_規則一
,所以規則一的條件也繼承了。
Car car = new Car(); Customer customer = new Customer(); customer.setAge(65); kieSession.insert(customer); kieSession.insert(car); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("rule_extends_"));
客戶有車,并且年齡是65歲,滿足上方的規則一和規則二
觸發規則一:用戶年齡>60歲,打0.9折
觸發規則二:用戶有車,免費停車
可以看到在rule
上使用extends
關鍵字,可以實現規則的繼承。
只要用戶大于60歲,直接打0.9折,如果還有車,則可以免費停車。
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
解釋:
見上方的規則文件里的注視
Car car = new Car(); Customer customer = new Customer(); customer.setAge(65); kieSession.insert(customer); kieSession.insert(car); kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("命名結果_"));
用戶年齡>60歲,打0.9折
用戶有車,免費停車
也實現了需求
通過when
中使用 do[名字]
然后 then
then 名字
也可以實現。
完成類似 if else if else
效果。見下方的各種執行結果。
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
1、Customer
的age
小于60
。輸出:
沒有輸出。
2、Customer
的age
大于60
并且level=1
,沒有Car
。輸出:
level1
3、Customer
的age
大于60
并且level=1
,有Car
。輸出:
level1 我執行了
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 我執行了
do
:執行完之后,還會繼續判斷后面的執行條件。 (即還會執行后面的Car判斷,根據是否有Car獲取不同的結果
)break
:執行完之后,不會在判斷后面的執行條件。(即忽略了后面的Car判斷,rule執行完了
)
關于“drools中then部分怎么寫”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。