Drools(規則引擎)簡單演示

項目結構
在這裏插入圖片描述
pom文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.drools</groupId>
    <artifactId>xyydrools</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <drools-version>7.0.0.Final</drools-version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>${drools-version}</version>
        </dependency>
    </dependencies>
</project>

商品類

package com.xyy;

public class Product {

    /**
     * 鑽石
     */
    public static final String DIAMOND = "0";

    /**
     * 黃金
     */
    public static final String GOLD = "1";
    /**
     * 類型
     */
    private String type;
    /**
     * 折扣
     */
    private int discount;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getDiscount() {
        return discount;
    }

    public void setDiscount(int discount) {
        this.discount = discount;
    }
}

resource文件下的這兩個文件要格外注意在此目錄下新建一個包com.rules
在新建一個文件Rules.drl
不用擔心文件格式找不到,idea是集成了drools的

package com.rules

import com.xyy.Product

rule Offer4Diamond
    when
        productObject : Product(type == Product.DIAMOND)
    then
        productObject.setDiscount(15);
    end
rule Offer4Gold
    when
        productObject: Product(type == Product.GOLD)
    then
        productObject.setDiscount(25);
    end

META-INF下的kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules" packages="com.rules">
        <ksession name="ksession-rule"/>
    </kbase>

    <!--
    Kmodule中可以包含一個到多個kbase,分別對應drl的規則文件。
Kbase需要一個唯一的name,可以取任意字符串。
packages爲drl文件所在resource目錄下的路徑。注意區分drl文件中的package與此處的package不一定相同。多個包用逗號分隔。默認情況下會掃描resources目錄下所有(包含子目錄)規則文件。
kbase的default屬性,標示當前KieBase是不是默認的,如果是默認的則不用名稱就可以查找到該KieBase,但每個module最多只能有一個默認KieBase。
kbase下面可以有一個或多個ksession,ksession的name屬性必須設置,且必須唯一。
    -->
</kmodule>

Test

package com.xyy;

import org.drools.core.marshalling.impl.ProtobufMessages;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.definition.KnowledgePackage;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;

import java.util.Collection;

public class Drools5Test {

    public static void main(String[] args) {
        Drools5Test drools5Test = new Drools5Test();
        drools5Test.oldExecuteDrools();
    }

    private void oldExecuteDrools() {
        //KnowledgeBuilder收集已編寫的規則,生成編譯的KnowledgePackage集合
        // hasErrors()方法獲得編譯過程中是否有錯,getErrors()方法打印錯誤信息。支持.drl文件、.dslr文件和xls文件等。
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("com/rules/Rules.drl",
                this.getClass()), ResourceType.DRL);
        if (kbuilder.hasErrors()) {
            System.out.println(kbuilder.getErrors().toString());
        }
        //KnowledgePackage存放編譯之後規則的對象
        Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();

        //KnowledgeBase收集應用當中知識(knowledge)定義的知識庫對象(KnowledgePackage),
        // 在一個 KnowledgeBase 當中可以包含普通的規則(rule)、 規則流(rule flow)、函數定義(function)、
        // 用戶自定義對象(type model)等,並創建session對象(StatefulKnowledgeSession和 StatelessKnowledgeSession)
        KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
        // 將KnowledgePackage集合添加到KnowledgeBase當中
        knowledgeBase.addKnowledgePackages(pkgs);
        //StatefulKnowledgeSession接收外部插入的數據fact對象(POJO),
        // 將編譯好的規則包和業務數據通過fireAllRules()方法觸發所有的規則執行。使用完成需調用dispose()方法以釋放相關內存資源。
        StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession();
        Product product = new Product();
        product.setType(Product.DIAMOND);
        ksession.insert(product);
        ksession.fireAllRules();
        ksession.dispose();

        System.out.println("The discount for the product " + product.getType()
                + " is " + product.getDiscount()+"%");
    }

    @Test
    public void testRules() {
        // 構建KieServices
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();
        // 獲取kmodule.xml中配置中名稱爲ksession-rule的session,默認爲有狀態的。
        KieSession kSession = kieContainer.newKieSession("ksession-rule");

        Product product = new Product();
        product.setType(Product.DIAMOND);

        kSession.insert(product);
        int count = kSession.fireAllRules();
        System.out.println("命中了" + count + "條規則!");
        System.out.println("商品" +product.getType() + "的商品折扣爲" + product.getDiscount() + "%。");

    }
}

演示結果:
在這裏插入圖片描述
在這裏插入圖片描述
其他想要說的話:
drools可以看作你定義好的一個方法,方法裏是各種if,else,
滿足if就滿足了這個規則,就會觸發規則規定的情況,比如是打幾折,這個東西是作者在一個項目中第一次接觸,也參考了相應的文章,在此記錄一下。這個東西一般大型的項目會用到,或者特殊需求的項目也可能會用到,網上也有這個東西的介紹和學習。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章