Drools(规则引擎)简单演示
程序员文章站
2022-05-22 11:13:47
...
项目结构
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就满足了这个规则,就会触发规则规定的情况,比如是打几折,这个东西是作者在一个项目中第一次接触,也参考了相应的文章,在此记录一下。这个东西一般大型的项目会用到,或者特殊需求的项目也可能会用到,网上也有这个东西的介绍和学习。
推荐阅读
-
RuleEngine -- 一款使用简单,入门方便的数据库规则引擎 中间件规则引擎JavaRuleEngine
-
Drools 5.2 发布:开源的业务规则引擎
-
drools规则引擎与kie-wb和kie-server远程执行规则(7.18.0.Final)
-
SpringBoot整合Drools规则引擎动态生成业务规则的实现
-
Drools规则引擎-Drools入门案例
-
开源力量公开课第70期:新一代规则引擎Drools概览
-
规则引擎Drools的资料整理
-
Spring Boot中使用Drools规则引擎
-
Drools规则引擎-判断集合(List)是否包含集合
-
规则引擎Drools example3说明