• drools基本知识


    一、概述

    kie(Knowledge Is Everything)

    package rules.rulesHello  //规则逻辑路径
       rule "test001"  //rule 规则开始 "test001" 规则名
             when
                   eval(true);  //规则条件
             then
                 System.out.println("hello world"); //规则返回结果
        end  //规则结束

    规则文件内容包含三大块 :包路径,引用,规则体(核心)

    规则体:分为 LHS,RHS两大功能模块

    1.LHS(Left Hand Side):条件部分,when与then中间部分

    2.RHS(Right Hand Side):结果部分,then与end中间部分

    Drools规则引擎中传递的数据,术语称Fact对象,Fact对象是一个普通的javaBean,规则体可以对当前对象进行任何的读写操作。Fact插入Working Memory(内存储存)


    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
       <kbase name="rules" packages="rules.rulesHello">
           <ksession name="testhelloWorld"/>
       </kbase>
    </kmodule>

    (1)一个kmodule.xml配置可以包含多个kbase

    (2)kbase的packages属性,值为src/main/resources目录下文件夹名称,可以同时定义多个包,以逗号进行分隔。可以包含多个ksession

    (3)每个ksession,名称可以是任意字符,不能重复

    (4)packages指定的所有规则文件都会读取,子目录中规则文件不会被加载


    @Test
       public void test2(){
           //单例模式创建KieServices,可以访问所以KIE构建和运行时的接口,初始化过程
           KieServices kieServices = KieServices.Factory.get();
           //KieContainer读取路径中需要构建的文件,是KIE的容器,初始化过程、、、、
           //创建KieModule,KieBase,KieSession对象,KieModule和KieBase只会创建一次
           KieContainer kc = kieServices.getKieClasspathContainer();
           //新建一个KIE会话
           KieSession ks = kc.newKieSession("testhelloWorld");
           Person person=new Person();
           person.setName("zhangsan");
           person.setAge(12);
           FactHandle insert = ks.insert(person);
           System.out.println(insert);
           //执行规则
           int i = ks.fireAllRules();
           System.out.println(i);
           ks.dispose();
      }

    二、基础语法

    规则文件关键字:

    关键字概述
    package 包名,只限于逻辑上的管理,若自定义的查询或函数位于同一包名,不管物理位置如何,都可以直接调用
    import 规则引用问题,导入类或方法
    global 全局变量
    function 自定义函数
    queries 查询
    rule end 规则体

    规则体语法结构

    关键字描述
    rule 规则开始,参数是规则的唯一名称
    attributes 规则属性,是rule与when之间的参数,为可选项
    when 规则条件部分,默认为true
    then 规则结果部分
    end 当前规则结束

    pattern(匹配模式)

    规则体中LHS部分绑定变量基本上两种形式:

    一种:整个Fact变量的绑定


    rule "rule1"
     when
     $customer:Customer(age>25,gender=='male')
     then
    ....
    end

    另一种:约束条件属性变量的绑定


    rule "rule1"
     when
     $customer:Customer(age>25,$g:gender=='male')
     then
    ....
    end

    约束连接

    “&&”(and) "||"(or) ","(and)

    contains 比较操作符:

    语法:Object(field[Collection/Array] contains|not contains value)

    memberOf 比较运算符:判断某个Fact对象的某个字段是否在一个或多个集合中

    语法:Object(fieldName memberOf|not memberOf value[Collection/Array])

    matches比较运算符:用来对某个Fact对象的字段与标准的Java正则表达式进行相似匹配

    语法:Object(fieldName matches|not matches "正则表达式")

    soundslike比较运算符:用来检查单词是否具有与给定值几乎相同的声音(使用英语发音)

    语法:Object(fieldName soundslike 'value')

    str 比较运算符:检查String字段是否以某一值开头/结尾,还可以判断字符串长度

    语法:Object(fieldName str[startsWith|endsWith|length])

    三、规则属性

    1.no-loop

    默认值:false

    类型:Boolean。

    属性说明:防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使规则再次被激活,从而导致死循环。

    2.ruleflow-group

    默认值:N/A

    类型:String

    属性说明:ruleflow-group分为rule、flow和group3个部分,分别代表规则、流程、分组,即常说的规则流。

    3.lock-on-active

    默认值:false

    类型:Boolean

    属性说明:lock-on-active是指“锁定活跃”

    4.salience

    默认值:0

    类型:integer

    属性说明:规则体被执行的顺序,每一个规则都有一个默认的执行shunxu,如果不设置sailence属性,规则体的执行顺序为由上到下。salience值可以是一个整数,也可以是个负数,值越大,执行顺序越高,排名靠前。

    5.enabled

    默认值:true

    类型:Boolean

    属性说明:指规则是否可以被执行,若规则体设置为enabled false,则规则体将视为永久不被激活

    6.dialect

    可能值:Java或Mvel

    类型:String

    属性说明:用来定义规则中要使用的语言类型,支持Mvel和java两种类型的语言

    7.date-effective

    默认值:N/A

    类型:String、日期、时间

    属性说明:只有当前系统时间大于等于设置的时间或日期,规则才会被激活。在没有设置该属性的情况下,规则体不受时间限制。可接受日期格式“dd-MMM-yyyy" 如:date-effective “25-October-2019"

    8.date-expires

    默认值:N/A

    类型:String、日期、时间

    属性说明:date-expires属性与date-effective属性相反,只有当前系统时间小于设置的时间或日期,规则才会激活 修改日期格式:通过 System。setProperty(“drools.dateformat","yyyy-MM-dd HH:mm:ss")

    9.duration

    默认值:无

    类型:long

    属性说明:表示定时器,如果当前规则LHS部分为true,那么规则继续执行;如果该属性已经被弃用,那么通过新的属性timer来控制

    10.activation-group

    默认值:N/A

    类型:String

    属性说明:activation-group是指激活分组,通过字符串定义分组名称,具有相同组名称的规则体有且只有一个规则被激活,其他规则体的LHS部分仍然为true也不会再被执行。该属性受salience属性的影响,如当前规则文件中的其他规则未设计该属性,则视为规则处于被激活状态,并不受该属性的影响。

    11.agenda-group

    默认值:无,需要通过Java设置

    类型:String

    属性说明: agenda-group是议程分组,属于另一种可控的规则执行方式,是指用户可以通过配置agenda-group的参数来控制规则的执行,而且只有获取焦点的规则才会被激活。


    ks.getAgenda().getAgendaGroup("ag1").setFocus();//让AgendaGroup分组为ag1的获取焦点

    12.auto-focus

    默认值:false

    类型:boolean

    属性说明:auto-focus属性为自动获取焦点,即当前规则是否被激活。如果一个规则被执行,那么认为auto-focus为true;如果单独设置,一般结合agenda-group,当一个议程组未获取焦点时,可以设置auto-focus来控制

    13.timer

    默认值:无

    类型:与java定时器参数类型相似

    属性说明:timer是一个定时器,用来控制规则的执行时间,两种写法:


    //第一种
    timer(int:<initial delay> <repeat interval>?)
    timer(int: 30s)
    timer(int: 30s 5m)
    //第二种
    timer(cron: <cron expression>)
    timer(cron: * 0/15 * * * ?)

    四、中级语法

    1.global全局变量

    1.常量值是不能改变的

    2.包装类是不能改变的

    3.类似javaBean、List类的操作是可以改变内容的,但内存地址不变

    2.query查询

    以query开始、以end结束


    package rules.rulesHello
    import com.mufeng.rules.pojo.Person;
    //"person age is 30 and name is 张三" 名称
    // (String $name) 参数 (多个可以用","分隔)
    query "person age is 30 and name is 张三" (String $name)
        person:Person(name==$name,age==30)
    end

    3.function函数

    规则中函数有两种形式:

    一种:在规则中添加关键字function


    package rules.isFunction
    rule "function1"
       when
       then
        System.out.println(function1("王二"));
        end

    function String function1(String name){
    System.out.println("name:"+name);
    return name;
    }

    另一种:import,引用java静态方法

    4.declare声明

    功能:1.声明新类型,2.声明元数据类型

    package rules.rulesHello

    declare Person1 extends com.mufeng.rules.pojo.Person //声明 extends加继承
       type:String
    end

    rule "de1"
    when
    then
    Person1 p=new Person1();
    p.setName("张三");
    p.setType("2");
    insert(p);
    end
    rule "de"
    when
    $p:Person1(name=="张三")
    then
      System.out.println($p.getType());
      System.out.println($p);
    end

    4.规则when

    对象属性有3中类型的限制:单值限制、复合值限制和多限制

    单值限制:(name=="张三")

    1.复合值限制in/not in

    Person(className in ("一班","二班",$cn))

    2.条件元素eval

    eval(expression) :任何语义代码,并返回一个boolean类型

    3.条件元素not

    判断工作内存中是否存在某个值,如 not Person();

    4.条件元素exists

    与not相反,判断工作内存中存在某个值,如 exists Person();

    5.条件元素forall

    与eval()功能相似,通过模式匹配对forall进行判断,当完全匹配是,forall为true。


    forall(p:Person(name=="张三") Person(this==p,age==30))

    6.条件元素from

    可以让用户指定任意的资源,用于LHS部分的数据匹配,也可以用来对集合进行遍历,还可以用来对java服务进行访问并就结果进行遍历 如 from listFrom("张三",10) listFrom为静态方法,返回list集合

    7.条件元素collect

    需要结合from来使用 from collect 用来汇总的

    8.条件元素accumulate(功能强大)

    允许规则迭代整个对象的集合,为每个元素定制执行动作,并在结束时返回一个结果对象,支持预定义的累积函数的使用,也可以使用其他内置函数,还可以使用自定义函数进行特殊化操作。

    内置包括:average(平均值)、min(最小值)、max(最大值)、count(统计)、sum(求和)、collectList(返回List)、collectSet(返回HashSet)

    inline的语法结构:


    <result pattern> from  accumulate(<source patterm>,init(<init code>),action(<action code>),reverse(<reverse code>),result(<result expression>))

    自定义定制:新建 TestAccumulate并实现AccumulateFunction目录为com/rulesAccumulate

    9.条件元素规则继承

    与java相似,


    rule "No2" extends "No1"

    10.条件元素do对应多then同条件


    rule "test"
     when
      $p:Person(name=="张三")
      do[then03]
      do[then03]
     then
       System.out.println("......");
     then[then01]
       System.out.println("******");
     then[then03]
       System.out.println("******");
    end

    1.使用do时,do的参数与then的参数必须有对应关系。

    2.then可以不与do成对出现

    3.使用do时,do后的参数在RHS中是必须要存在的,参数是一个zhizhen。

    4.使用修改时,在非update情况下,then部分都会被执行。

    5.使用修改时,在update情况下,then部分是有优先级的,是根据do的顺序控制的,但没有参数的then可能会改变其他的RHS部分。

    6.使用do时,顺序控制是至关重要的。

    7.无参数的then,优先级可能会低于指定的do。

    8.do只能在其他条件元素之后使用。

    5.规则then

    操作命名:

    update(Fact事实对象)

    insert(new Object())

    insertLogical(new Object())

    delete(handle)

    modify(<fact-expression>){

    <expression>[,<expression>]*

    }


    modify($p){
       setAge(50),
       setName("李四")
    }

    drools.halt():立即终止规则执行。

    drools.geWorkingMemory():返回WorkingMemory对象。

    drools.setFocus(String s):将焦点放在指定的议程组上。

    drools.getRule().getName():返回规则的名称。

    drools.getTule():返回与当前正在执行的规则匹配的数组,并且为drools.getActivation()提供相应的激活

    6.kmodule配置说明

    kmodule.xml文件放到src/main/resources/META-INF/文件夹下


    <?xml version="1.0" encoding="UTF-8"?>
    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
       <kbase name="rules" packages="rules.rulesHello">
           <ksession name="testhelloWorld"/>
       </kbase>
       <kbase name="query" packages="rules.isQuery">
           <ksession name="isQuery"/>
       </kbase>
       <kbase name="function" packages="rules.isFunction">
           <ksession name="isFunction"/>
       </kbase>
    </kmodule>

    五、KieSession状态

    有状态的KieSession:

    需要清理KieSession的状态,调用dispose()方法,如果在调用规则时不调用dispose()方法,则KieSession.insert(Object)会产生迭代方法插入的(笛卡尔积)

    无状态的StatelessKieSession

    execute()默认调用dispose()方法

    六、Drools高级用法

    1.决策表

     注释行:package包路径 
    关键字 RuleSet rulesTwo.isXls  
    关键字 RuleTable 测试规则    
    关键字 CONDITION ACTION  
    条件区      
    条件区 eval(true); System.out.println("$param");  
    条件注释行      
    规则值说明   测试规则_7  
    规则值说明   测试规则_8  
    规则值说明   测试规则_9  

    1.RuleSet和drl文件中package功能是一样的,为必填项

    2.RuleTable和drl文件中规则名称的功能是一样的,为必填项

    3.CONDITION和规则体中LHS部分功能是一样的,为必填项

    4.ACTION和规则体中RHS部分功能是一样的,为必填项

    检查决策表生成drl文件是否正确


    <dependency>
       <groupId>org.drools</groupId>
       <artifactId>drools-decisiontables</artifactId>
       <version>${drools.version}</version>
    </dependency>

    @Test
    public void test7() throws FileNotFoundException {
       File file=new File("D:\Development\idea\workspace\spring\boot\drools-test\src\main\resources\rulesTwo\isXls.xls");
       InputStream fileInputStream = new FileInputStream(file);
       SpreadsheetCompiler spreadsheetCompiler = new SpreadsheetCompiler();
       String compile = spreadsheetCompiler.compile(fileInputStream, InputType.XLS);
       System.out.println(compile);
    }

    占位符: 1、$2

    2.DSL领域语言(略)

    3.规则模板

    cheese.xls

         
      年龄 className log  
      50 一班 1  
      40 二班 2  
      30 三班 3  
      20 四班 4  
             

    cheese.drt


    template header
    age
    className

    package rulesTwo.isDrt;
    import com.mufeng.rules.pojo.Person;

    template "cheesefans"

    rule "cheese fans_@{row.rowNumber}"
    no-loop true
      when
        $p:Person(age==@{age})
      then
        $p.setClassName("@{className}");
        update($p);
    end
    end template

    规则模板文件以template header开头,以end template结尾 age表示Excel文件的列 相当于占位符


    <kbase name="isDrt" packages="rulesTwo.isDrt">
       <ruleTemplate dtable="rulesTwo/isDrt/cheese.xls" template="rulesTwo/isDrt/cheese.drt" row="3" col="2"/>
       <ksession name="isDrt"/>
    </kbase>

    row="3" 从第三行取数据 col="2" 从第二行取数据


    @Test
    public void test8(){
       KieServices kieServices = KieServices.Factory.get();
       KieContainer kc = kieServices.getKieClasspathContainer();
       KieSession ks = kc.newKieSession("isDrt");
       Person person=new Person("张三",50);
       ks.insert(person);
       int i = ks.fireAllRules();
       System.out.println(i);
       System.out.println(person.getClassName());
       ks.dispose();
    }

    第二种获取方法:


    @Test
    public void test9(){
       
       ObjectDataCompiler converter = new ObjectDataCompiler();
       Person person=new Person();
       person.setAge(50);
       person.setClassName("一班");
       List<Person> cfl=new ArrayList<>();
       cfl.add(person);
       InputStream inputStream =null;
       try {
           inputStream=ResourceFactory.newClassPathResource("rulesTwo\isDrt\cheese.drt", Test1.class).getInputStream();
      } catch (IOException e) {
           e.printStackTrace();
      }
       String drl = converter.compile(cfl, inputStream);
       System.out.println(drl);
       KieHelper kieHelper=new KieHelper();
       kieHelper.addContent(drl, ResourceType.DRL);
       KieSession kieSession = kieHelper.build().newKieSession();
       Person person1=new Person();
       person1.setAge(50);
       person1.setName("张三");
       kieSession.insert(person1);
       int i = kieSession.fireAllRules();
       System.out.println(i);
       kieSession.dispose();
    }

    4.规则流(略)

    5.Drools事件监听

    RuleRuntimeEvenListener,AgendaEventListener,ProcessEventListener3个接口

    七、Workbench

    1.安装与配置

    1.安装jdk

    2.安装tomcat

    http://tomcat.apache.org/download-70.cgi

    3.下载Workbench的war包,http://www.drools.org/download/download.html

    安装说明:

    (1)将war包放在webapps/目录下,并改名为kie-wb.war

    (2)将下列jar复制到TOMCAT_HOME/lib中:

    btm-2.1.4.jar

    btm-tomcat55-lifecycle-2.1.4.jar

    h2-1.3.161.jar

    jta-1.1.jar

    slf4j-api-1.7.2.jar

    slf4j-jdk14-1.7.2.jar

    log4j-api-2.1.jar

    log4j-slf4j-impl-2.1.jar


    <dependency>
       <groupId>org.codehaus.btm</groupId>
       <artifactId>btm</artifactId>
       <version>2.1.4</version>
    </dependency>
    <dependency>
       <groupId>org.codehaus.btm</groupId>
       <artifactId>btm-tomcat55-lifecycle</artifactId>
       <version>2.1.4</version>
    </dependency>
    <dependency>
       <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <version>1.3.161</version>
    </dependency>
    <dependency>
       <groupId>javax.transaction</groupId>
       <artifactId>jta</artifactId>
       <version>1.1</version>
    </dependency>
    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.2</version>
    </dependency>
    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-jdk14</artifactId>
       <version>1.7.2</version>
    </dependency>
    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <version>2.1</version>
    </dependency>
    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-slf4j-impl</artifactId>
       <version>2.1</version>
    </dependency>

    (3)在TOMCAT_HOME/conf目录下,新建btm-config.properties(每个语句后面不能有空格)


    bitronix.tm.serverId=tomcat-btm-node0
    bitronix.tm.journal.disk.logPart1Filename=${btm.root}/work/btm1.tlog
    bitronix.tm.journal.disk.logPart2Filename=${btm.root}/work/btm2.tlog
    bitronix.tm.resource.configuration=${btm.root}/conf/resources.properties

    在TOMCAT_HOME/conf下,新建resources.properties,


    resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
    resource.ds1.uniqueName=jdbc/jbpm
    resource.ds1.minPoolSize=10
    resource.ds1.maxPoolSize=20
    resource.ds1.driverProperties.driverClassName=org.h2.Driver
    resource.ds1.driverProperties.url=jdbc:h2:file:~/jbpm
    resource.ds1.driverProperties.user=sa
    resource.ds1.driverProperties.password=
    resource.ds1.allowLocalTransactions=true

    (4)在TOMCAT_HOME/bin目录下,新建setenv.sh


    CATALINA_OPTS="-Xmx512M - XX:MaxPermSize=512m -Dbtm.root=$CATALINA_HOME
    -Dbitronix.tm.configuration=$CATALINA_HOME/conf/btm-config.properties
    -Djbpm.tsr.jndi.lookup=java:comp/env/TransactionSynchronizationRegistry
    -Djava.security.auth.login.config=$CATALINA_HOME/webapps/kie-web/WEB-INF/classes/login.config
    -Dorg.jboss.logging.provider=jdk
    -Dorg.jbpm.cdi.bm=java:comp/env/BeanManager
    -Dorg.guvnor.m2repo.dir=/root/.m2/repository
    -Dorg.kie.demo=false
    -Dorg.kie.example=false"

    (5)配置JEE security

    把下面3个jar包放到TOMCAT_HOME/lib下


    <dependency>
       <groupId>javax.security.jacc</groupId>
       <artifactId>javax.security.jacc-api</artifactId>
       <version>1.5</version>
    </dependency>
    <dependency>
       <groupId>org.kie</groupId>
       <artifactId>kie-tomcat-integration</artifactId>
       <version>${drools.version}</version>
    </dependency>
    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.2</version>
    </dependency>

    (6)在TOMCAT_HOME/conf/server.xml的Host节点最后添加


    <Value className="org.kie.integration.tomcat.JACCValve"/>

    (7)编辑TOMCAT_HOME/conf/tomcat-users.xml,添加‘analyst'或’admin‘角色,添加KIE-WB相应的用户


    <role rolename="admin"/>
    <role rolename="analyst"/>
    <user username="kie" password="kie" roles="admin"/>
    <user username="kie-analyst" password="kie-analyst" roles="analyst"/>

    (8)启动tomcat,访问 “8080/kie-wb" perfect

     

  • 相关阅读:
    如何使用WPF用户界面框架编译EasyPlayPro-Win版本网页无插件视频播放器?
    【解决方案】TSINGSEE青犀视频智慧校园解决方案
    TSINGSEE青犀视频开发rtp推流如何使用ffmpeg配置rtp打包模式?
    TSINGSEE青犀视频部署流媒体服务器如何通过分布式存储突破设备接入及存储瓶颈?
    mysql--存储引擎
    数据库-基本操作
    初识数据库
    mysql---索引
    数据类型--mysql
    mysql--权限问题
  • 原文地址:https://www.cnblogs.com/mufeng07/p/12626251.html
Copyright © 2020-2023  润新知