Drools 規則引擎環境搭建

1、關於 drools 規則引擎

前面寫過一篇 Drools 規則引擎相關的文章,這篇文章主要記錄一下規則引擎的環境搭建和簡單示例。不熟悉 drools 的朋友能夠看看這篇文章: 本身寫個 Drools 文件語法檢查工具——棧的應用之編譯器檢測語法錯誤
介紹的內容:html

  • Drools 規則引擎的使用場景
  • Drools 規則引擎的優勢
  • Drools的基本工做工程(Fact對象、Drl文件內容、Drools的基礎語法)
  • drools 文件的形式
  • Drools 文件語法初步檢查

二 、Drools 的環境搭建及簡單示例

環境: idea + jdk1.8 + gradle
我用的是 gradle 構建 java 工程的方式、用 maven 構建的能夠參考配置java

構造這樣一個需求背景,雙十一來了,商品打折,假設商品價格 (0,500], 打85折,商品價格 (500, 1000],打8折, 商品價格 (1000,∞), 一概減 300。api

1. 建立項目

新建一個 gradle 項目,建立包:com.sharpcj,新建類 Product.javaMain.java
session

Product.java 文件以下:app

package com.sharpcj;

public class Product {
    private String name;  // 商品名稱
    private double prePrice;  // 商品訂價
    private double realPrice;  //商品實際售價

    public Product() {
    }

    public Product(String name, double prePrice) {
        this.name = name;
        this.prePrice = prePrice;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrePrice() {
        return prePrice;
    }

    public void setPrePrice(double prePrice) {
        this.prePrice = prePrice;
    }

    public double getRealPrice() {
        return realPrice;
    }

    public void setRealPrice(double realPrice) {
        this.realPrice = realPrice;
    }
}

而後在 Main.java 新建 main 方法。less

2. Gradle引入Drools庫

打開 build.gradle 文件,添加相應的插件和依賴maven

plugins {
    id 'java'
}

plugins {
    id 'application'
}

mainClassName = 'com.sharpcj.Main'

group 'com.sharpcj'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.kie', name: 'kie-api', version: '7.5.0.Final'
    compile group: 'org.drools', name: 'drools-compiler', version: '7.5.0.Final'
}

引入 Java 插件,使Gradle能夠構建Java代碼,同時引入了執行Drools依賴的兩個庫, 指定了 mainClassNameide

3.編寫 drools 文件

resources 目錄下面新建包 demo.rules,用來存放 drools 規則文件。而後新建文件 product.drl
工具

內容以下:測試

package com.sharpcj;

rule "Product price less than 500" // 給規則取個名
when
    pp : Product( prePrice <= 500 ) // 規則
then
    // 符合規則後執行的操做,是Java代碼
    double prePrice = pp.getPrePrice();
    pp.setRealPrice(prePrice * 0.85);
    System.out.println(pp.getName() + "活動價是:" + pp.getRealPrice());
end


rule "Product price less than 1000" // 給規則取個名
when
    p : Product( prePrice > 500 && prePrice <=1000 ) // 規則
then
    // 符合規則後執行的操做,是Java代碼
    double prePrice = p.getPrePrice();
    p.setRealPrice(prePrice * 0.8);
    System.out.println(p.getName() + "活動價是:" + p.getRealPrice());
end


rule "Product price more than 1000" // 給規則取個名
when
    p : Product( prePrice > 1000 ) // 規則
then
    // 符合規則後執行的操做,是Java代碼
    double prePrice = p.getPrePrice();
    p.setRealPrice(prePrice - 300);
    System.out.println(p.getName() + "活動價是:" + p.getRealPrice());
end

4.編寫配置文件

運行 drools 須要一個固定的配置文件,在 resources 文件下的目錄 META_INF,名稱固定爲 kmodule.xml

配置文件至少包含以下幾行:

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="kbase1" packages="demo.rules">
        <ksession name="ksession1" />
    </kbase>
</kmodule>

配置簡單說明:

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

5.讓規則文件程序跑起來

Main.java 類中編寫測試方法,讓規則文件跑起來:

package com.sharpcj;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class Main {
    public static void main(String[] args){
        new Main().test();
    }

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

        Product fan = new Product("電扇", 280);
        Product washer = new Product("洗衣機",2200);
        Product phone = new Product("手機", 998);
        kSession.insert(fan);
        kSession.insert(washer);
        kSession.insert(phone);
        kSession.fireAllRules();
        kSession.dispose();
    }
}

運行結果:

3、其它說明

1.不使用配置文件形式

上面使用的配置文件形式加載 drools 文件是 drools 7.x 版本纔有的,在此以前,咱們一般使用代碼形式加載規則文件,固然在 drools 7.x 中依然可使用這種方式,只不過有些 API 已通過時了,或者更新了。下面用代碼形式加載規則文件代碼以下:

/**
     * 不使用 drools 7.x 配置文件
     */
    private void test2(){
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("demo/rules/product.drl"), ResourceType.DRL);

        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }


        // 註釋掉的是 drools 6.x API
        /*KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();*/

        // drools 7.x API
        InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        Collection<KiePackage> pkgs = kbuilder.getKnowledgePackages();
        kbase.addPackages(pkgs);
        KieSession kieSession = kbase.newKieSession();
        Product fan = new Product("電扇", 280);
        Product washer = new Product("洗衣機",2200);
        Product phone = new Product("手機", 998);
        kieSession.insert(fan);
        kieSession.insert(washer);
        kieSession.insert(phone);
        kieSession.fireAllRules();
        kieSession.dispose();
    }

運行程序依然能獲得相同的結果。

2.規則文件的類型

規則文件除了 drl 文件之類,還有其它類型的文件,如 xls, csv。

4、附錄

Drools 官網首頁: https://www.drools.org/
Drools 官方文檔: https://docs.jboss.org/drools/release/7.12.0.Final/drools-docs/html_single/index.html

相關文章
相關標籤/搜索