項目結構
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就滿足了這個規則,就會觸發規則規定的情況,比如是打幾折,這個東西是作者在一個項目中第一次接觸,也參考了相應的文章,在此記錄一下。這個東西一般大型的項目會用到,或者特殊需求的項目也可能會用到,網上也有這個東西的介紹和學習。