規則引擎drools的簡單使用

規則引擎適用於有複雜多變的規則,如商品滿減、積分贈送、考勤規則等html

1、引入maven依賴java

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>7.13.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.13.0.Final</version>
</dependency>

  

2、drools有兩種執行方式,第一種是基於kmodule.xml、drl配置文件,第二種是動態讀取規則數據庫

基於kmodule方式session

 1)建立Fact,drools中的Fact便是java中的普通的bean,用於傳遞參數maven

package com.beyond.odc.entity;

/**
 * Fact java bean
 * @author Hejinsheng
 */
public class Message {

    private String message;

    private String result;

    private int status;

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getStatus() {
        return this.status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

  

 2)在resources/META-INF下建立kmodule.xml文件,內容以下oop

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>

  

3)在resources/rules文件夾下建立規則描述文件rules.drl,內容以下測試

package rules

import com.beyond.odc.entity.Message;

rule "hello"
    no-loop true
    lock-on-active true
    when
        $message:Message(status==0)
    then
        System.out.println("消息:"+$message.getMessage());
        $message.setResult("hello 響應的消息");
        update($message)
end

rule "byebye"
    no-loop true
    lock-on-active true
    when
        $message:Message(status==1)
    then
        System.out.println("消息:"+$message.getMessage());
        $message.setResult("byebye 響應的消息");
        update($message)
end

  

 4)編寫測試文件ui

public static void main(String[] args) {
       try {

            KieSession kSession = KieContainerFactory.getKieContainer().newKieSession("ksession-rules");

            Message message = new Message();
            message.setMessage("hello");    // 對應drl文件中的rule name,表示要執行的規則
            message.setStatus(0);           // 取message中的某個字段,用戶規則文件中的判斷是否執行代碼塊
            kSession.insert(message);       // 將message做爲傳遞的參數傳入drools執行
            kSession.fireAllRules();        // 加載規則
            System.out.println("從drools中接收到的消息:"+message.getResult());    // drools中若是有參數響應,能夠經過字段獲取
        } catch (Throwable t) {
            t.printStackTrace();
        }
}

  

//KieContainerFactory代碼片斷
public class KieContainerFactory {

    private static KieContainer kieContainer;

    public static KieContainer getKieContainer() {
        if(kieContainer == null){
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            kieContainer = kContainer;
        }
        return kieContainer;
    }
}

  

5)執行結果,說明代碼已經執行到drools文件中,具體的業務邏輯能夠在then後的代碼塊中實現this

進來了,消息:hello
從drools中接收到的消息:hello 響應的消息

  

3、動態方式執行spa

通常指從數據庫或者遠程獲取的規則描述信息,進行規則執行。動態方式不須要kmodule.xml和drl文件,執行上更加簡單

public static void execFromDB(){
        KieSession kSession = null;
        try {
            // 實際狀況從數據庫根據code查規則,這裏模擬寫死
            String rule = "package rules\n" +
                    "\n" +
                    "import com.beyond.odc.entity.Message;\n" +
                    "\n" +
                    "rule \"hello\"\n" +
                    "    no-loop true\n" +
                    "    lock-on-active true\n" +
                    "    when\n" +
                    "        $message:Message(status==0)\n" +
                    "    then\n" +
                    "        System.out.println(\"動態執行,消息:\"+$message.getMessage());\n" +
                    "        $message.setResult(\"hello 響應的消息\");\n" +
                    "        update($message)\n" +
                    "end\n" +
                    "\n" +
                    "rule \"byebye\"\n" +
                    "    no-loop true\n" +
                    "    lock-on-active true\n" +
                    "    when\n" +
                    "        $message:Message(status==1)\n" +
                    "    then\n" +
                    "        System.out.println(\"動態執行,消息:\"+$message.getMessage());\n" +
                    "        $message.setResult(\"byebye 響應的消息\");\n" +
                    "        update($message)\n" +
                    "end";

            KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kb.add(ResourceFactory.newByteArrayResource(rule.getBytes("utf-8")), ResourceType.DRL);

            // 檢查規則正確性
            KnowledgeBuilderErrors errors = kb.getErrors();
            for (KnowledgeBuilderError error : errors) {
                System.out.println("規則文件正確性有誤:{}" + error);
            }
            InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
            kBase.addPackages(kb.getKnowledgePackages());

            // 執行規則
            kSession = kBase.newKieSession();
            // fact
            Message fact = new Message();
            fact.setMessage("byebye");
            fact.setStatus(1);
            kSession.insert(fact);
            kSession.fireAllRules();
            System.out.println("從drools規則中接收到的消息:"+fact.getResult());
        } catch (Exception e) {
            System.out.println("規則執行異常:{}"+e);
        } finally {
            if (null != kSession)
                kSession.dispose();
        }

    }

  執行結果以下:

動態執行,消息:byebye
從drools規則中接收到的消息:byebye 響應的消息
相關文章
相關標籤/搜索