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就满足了这个规则,就会触发规则规定的情况,比如是打几折,这个东西是作者在一个项目中第一次接触,也参考了相应的文章,在此记录一下。这个东西一般大型的项目会用到,或者特殊需求的项目也可能会用到,网上也有这个东西的介绍和学习。

发布了21 篇原创文章 · 获赞 1 · 访问量 398

猜你喜欢

转载自blog.csdn.net/qq_44909430/article/details/102910243
今日推荐