学习日志三

来源:互联网 发布:涂师傅数据恢复raw 编辑:程序博客网 时间:2024/06/07 22:16

规则详解

@2016/11/4


一个规则通常包括三个部分:

  • 属性部分(attribute)
  • 条件部分(LHS)
  • 结果部分(RHS)

LHS

  • 当LHS为空时,引擎会自动添加一个eval(true)的条件,所以LHS为空的规则总是返回true。
  • LHS部分事由一个或者多个条件组成,条件又称为pattern(匹配模式),多个pattern之间用and和or来进行连接,同时还可以使用括号赖确定pattern的优先级。
  • [绑定变量名:]Object([field约束])。绑定变量名是一个可选的别名,也可以用于对象的属性。field约束是指当前对象里相关字段的条件限制。field例子,下例中有俩个pattern,分别有三个约束,pattern之间没有连接词,引擎默认为and连接。

    $customer:Customer(age>20,gender==’male’)
    Order(customer==$customer,price>1000)

  • 约束连接,对于对象内部的多个约束的连接,可以采用“&&”
    (and)、“||”(or)和“,”(and)来实现。这三个连接符号如果没有用小括号来显示的定义优先级的话,那么它们的执行顺序是:“&&”(and)、“||”(or)和“,”

RHS

  • 在 RHS 当中可以使用 LHS 部分当中定义的绑定变量名(仅能使用当前LHS内定义的绑定变量名,即绑定变量名为规则内的局部变量)、设置的全局变量、或者是直接编写 Java 代码(对于要用到的 Java类,需要在规则文件当中用 import 将类导入后才能使用)
  • insert(new Object());将一个 Fact 对象插入到当前的 Working Memory,注意一旦调用 insert 宏函数,那么 Drools 会重新与所有的规则再重新匹配一次,对于没有设置 no-loop 属性为 true 的规则,如果条件满足,不管其之前是否执行过都会再执行一次
  • update(new Object());直接更新一个Fact对象,同上会重新执行一次所有的规则。
  • retract($fact);删除一个Fact对象,同上
  • Drools宏对象的常用方法:

    –getWorkingMemory() 获取当前的WorkingMemory对象

    –alt()在当前规则执行完成后,不再执行其它未执行的规则

    –getRule() 得到当前的规则对象

  • kcontext宏对象,得到当前的KnowledgeRuntime对象

  • modify 是一个表达式块,可以实现对Fact对象多个属性进行修改,修改完后会自动更新到当前Working Memory当中。系统中必将用上,所以给出例子
package testimport java.util.List;rule "rule1"    salience 2    when        $customer:Customer(name=="张三",age==20);    then        System.out.println("modify before customer        id:"+$customer.getId()+";age:"+$customer.getAge());        modify($customer){            setId("super man"),            setAge(30)        }endrule "rule2"    salience 1    when        $customer:Customer(name=="张三");    then        System.out.println("modify after customer id:"+$customer.getId()+";age:"+$customer.getAge());end

attribute

  • salience,在modify的例子中出现了,用于确定规则优先级,数字越大优先级越高。
  • no-loop,是否可以多次执行,在目前的业务中一般设为true.
  • date-effective,date-expires.由于目前的业务规则中不涉及规则控制,所以略过不提。
  • enabled,定义一个规则是否可用。当值为false时引擎将不会执行该规则
  • dialect,设置语言类型,选项为mval和java。默认java。
  • duration,比较有意思,可以开一个新的线程,对于duration的解释这里直接引用书上的内容

    对于一个规则来说,如果设置了该属性,那么规则将在该属性指定的值之后在另外一个 线程里触发。该属性对应的值为一个长整型,单位是毫秒

  • lock-on-active,规则流相关,no-loop的增强版。

  • activation-group,将若干个规则划分成一个组,用一个字符串来给这个组命名,这样在执行的时候,具有相同 activation-group 属性的规则中只要有一个会被执行,其它的规则都将不再执行。可以看作规则的互斥并行结构?
  • agenda-group,auto-focus,ruleflow-group,没看懂

查询

无参数查询

query "testQuery"customer:Customer(age>30,orders.size >10)end

参数查询

query "testQuery"(int $age,String $gender)customer:Customer(age>$age,gender==$gender)end

调用查询

public class Test {    public static void main(String[] args) {        KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();        kb.add(new ClassPathResource("test/test.drl"), ResourceType.DRL);        KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();        knowledgeBase.addKnowledgePackages(kb.getKnowledgePackages());        StatefulKnowledgeSession statefulSession = knowledgeBase.newStatefulKnowledgeSession();//向当前WorkingMemory当中插入Customer对象        statefulSession.insert(generateCustomer("张三",20,"F"));        statefulSession.insert(generateCustomer("李四",33,"M"));        statefulSession.insert(generateCustomer("王二",43,"F"));//调用查询        QueryResults queryResults=statefulSession.getQueryResults("testQuery", new Object[]{new Integer(20),"F"});        for(QueryResultsRow qr:queryResults){            Customer cus=(Customer)qr.get("customer");//打印查询结果            System.out.println("customer name :"+cus.getName());        }        statefulSession.dispose();}/*** 产生Customer对象* */    public static Customer generateCustomer(String name,int age,String gender){        Customer cus=new Customer();        cus.setAge(age);        cus.setName(name);        cus.setGender(gender);        return cus;    }}

Fact对象

切记
Fact 对象就是普通的具有若干个属性及其对应的 getter 与 setter方法的 JavaBean 对象

Drools 除了可以接受用户在外部向 WorkingMemory 当中插入现成的Fact 对象,还允许用户在规则文件当中定义一个新的 Fact 对象,目前用不上,故省略。


Domain Specific Language

可能以后会用上吧。。。

0 0