zoukankan      html  css  js  c++  java
  • 规则引擎drools的简单使用

    规则引擎适用于有复杂多变的规则,如商品满减、积分赠送、考勤规则等

    一、引入maven依赖

    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>7.13.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>7.13.0.Final</version>
    </dependency>
    

      

    二、drools有两种执行方式,第一种是基于kmodule.xml、drl配置文件,第二种是动态读取规则

    基于kmodule方式

     1)创建Fact,drools中的Fact即是java中的普通的bean,用于传递参数

    package com.beyond.odc.entity;
    
    /**
     * Fact java bean
     * @author Hejinsheng
     */
    public class Message {
    
        private String message;
    
        private String result;
    
        private int status;
    
        public String getMessage() {
            return this.message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public int getStatus() {
            return this.status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public String getResult() {
            return result;
        }
    
        public void setResult(String result) {
            this.result = result;
        }
    }
    

      

     2)在resources/META-INF下创建kmodule.xml文件,内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
        <kbase name="rules" packages="rules">
            <ksession name="ksession-rules"/>
        </kbase>
    </kmodule>
    

      

    3)在resources/rules文件夹下创建规则描述文件rules.drl,内容如下

    package rules
    
    import com.beyond.odc.entity.Message;
    
    rule "hello"
        no-loop true
        lock-on-active true
        when
            $message:Message(status==0)
        then
            System.out.println("消息:"+$message.getMessage());
            $message.setResult("hello 响应的消息");
            update($message)
    end
    
    rule "byebye"
        no-loop true
        lock-on-active true
        when
            $message:Message(status==1)
        then
            System.out.println("消息:"+$message.getMessage());
            $message.setResult("byebye 响应的消息");
            update($message)
    end
    

      

     4)编写测试文件

    public static void main(String[] args) {
           try {
    
                KieSession kSession = KieContainerFactory.getKieContainer().newKieSession("ksession-rules");
    
                Message message = new Message();
                message.setMessage("hello");    // 对应drl文件中的rule name,表示要执行的规则
                message.setStatus(0);           // 取message中的某个字段,用户规则文件中的判断是否执行代码块
                kSession.insert(message);       // 将message作为传递的参数传入drools执行
                kSession.fireAllRules();        // 加载规则
                System.out.println("从drools中接收到的消息:"+message.getResult());    // drools中如果有参数响应,可以通过字段获取
            } catch (Throwable t) {
                t.printStackTrace();
            }
    }

      

    //KieContainerFactory代码片段
    public class KieContainerFactory {
    
        private static KieContainer kieContainer;
    
        public static KieContainer getKieContainer() {
            if(kieContainer == null){
                // load up the knowledge base
                KieServices ks = KieServices.Factory.get();
                KieContainer kContainer = ks.getKieClasspathContainer();
                kieContainer = kContainer;
            }
            return kieContainer;
        }
    }
    

      

    5)执行结果,说明代码已经执行到drools文件中,具体的业务逻辑可以在then后的代码块中实现

    进来了,消息:hello
    从drools中接收到的消息:hello 响应的消息
    

      

    三、动态方式执行

    一般指从数据库或者远程获取的规则描述信息,进行规则执行。动态方式不需要kmodule.xml和drl文件,执行上更加简单

    public static void execFromDB(){
            KieSession kSession = null;
            try {
                // 实际情况从数据库根据code查规则,这里模拟写死
                String rule = "package rules
    " +
                        "
    " +
                        "import com.beyond.odc.entity.Message;
    " +
                        "
    " +
                        "rule "hello"
    " +
                        "    no-loop true
    " +
                        "    lock-on-active true
    " +
                        "    when
    " +
                        "        $message:Message(status==0)
    " +
                        "    then
    " +
                        "        System.out.println("动态执行,消息:"+$message.getMessage());
    " +
                        "        $message.setResult("hello 响应的消息");
    " +
                        "        update($message)
    " +
                        "end
    " +
                        "
    " +
                        "rule "byebye"
    " +
                        "    no-loop true
    " +
                        "    lock-on-active true
    " +
                        "    when
    " +
                        "        $message:Message(status==1)
    " +
                        "    then
    " +
                        "        System.out.println("动态执行,消息:"+$message.getMessage());
    " +
                        "        $message.setResult("byebye 响应的消息");
    " +
                        "        update($message)
    " +
                        "end";
    
                KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
                kb.add(ResourceFactory.newByteArrayResource(rule.getBytes("utf-8")), ResourceType.DRL);
    
                // 检查规则正确性
                KnowledgeBuilderErrors errors = kb.getErrors();
                for (KnowledgeBuilderError error : errors) {
                    System.out.println("规则文件正确性有误:{}" + error);
                }
                InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
                kBase.addPackages(kb.getKnowledgePackages());
    
                // 执行规则
                kSession = kBase.newKieSession();
                // fact
                Message fact = new Message();
                fact.setMessage("byebye");
                fact.setStatus(1);
                kSession.insert(fact);
                kSession.fireAllRules();
                System.out.println("从drools规则中接收到的消息:"+fact.getResult());
            } catch (Exception e) {
                System.out.println("规则执行异常:{}"+e);
            } finally {
                if (null != kSession)
                    kSession.dispose();
            }
    
        }
    

      执行结果如下:

    动态执行,消息:byebye
    从drools规则中接收到的消息:byebye 响应的消息
    

      

  • 相关阅读:
    增加新分类daily——“每天学了啥?”
    gcc选项中的编译过程
    一个带路径复制的perl脚本
    git
    mysql explain 详解
    CentOS Python2.4升级到Python2.7
    mongoDb查询
    linux php 扩展
    php-redis 扩展安装
    redis Linux的安装方法
  • 原文地址:https://www.cnblogs.com/half-two-feet/p/9876684.html
Copyright © 2011-2022 走看看