drools 笔记

版本7.69

一、环境
    1、依赖包
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>6.3.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>6.3.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>6.3.0.Final</version>
        </dependency>
        第一个org。kie:kie-api依赖包含所有的公共接口暴露出来
    KIE平台,由Drools,jBPM,OptaPlanner。
        接下来,我们包括org。drools:drools-core工件,其中包含drools规则
    引擎的实现。
        最后,我们将包括org.drools:drools-compiler工件包含算法翻译规则写在不同的资源
    (文本文件、电子表格、自己的类型,等等)来执行规则。这个工件是必需的,只是因为我们在项目的编译我们的规则。是有可能的单独的规则编译规则执行删除这种依赖性从我们的项目,但是,为了简单起见,我们将编译我们的规则在同一个项目
    
    2、配置文件
    src/main/resources
        META-INF
            kmodule.xml    定义 kieBase , kieSession ...
            beans.xml    cdi配置用
        ***.drl
        ....drl    

二、规则语言
    agenda-group "B to C" 规则组,默认是主组,可以使用auto-focus true来指定可以从主进到该组(允许对多个规则设置auto-focus true,这样应该是按优先级来了),也可以使用drools.getKnowledgeRuntime().getAgenda().getAgendaGroup( "B to D" ).setFocus(); 进入对应组
    insertLogical 使对象驻留在工作内存中,直到插入他的条件不再为true

    1、update($*);
        或
    modify($*){
        setCategory(Category.LOW_RANGE)
    }
        可重新触发所有rule,而 $*.setCategory(Category.LOW_RANGE); 不会重新触发,继续触发能触发的rule
    
    2、insert(new Coupon($c, $o, Coupon.CouponType.POINTS));
    3、delete($cp);
    4、salience 10 rule执行顺序,默认0可以负,越大越优先,条件可动态 salience($i.getCost()) 
    5、no-loop 一次触发,在一次fireAll 中,只触发一次,哪怕中途 insert 了符合的条件
        只能起作用于自身规则引起的触发,其他规则引起的触发还是会触发一次
        可用 lock-on-active true
    6、lock-on-active true 再次触发也忽略
    6、global org.drools.devguide.eshop.service.EShopConfigService configService;
        enabled (configService.isMidHighCategoryEnabled())
        ksession.setGlobal("configService", mockService);
    7、enabled 是否需要触发该rule,enabled (动态条件)
    8、date-effective "01-Jan-2015"    规则生效时间
        date-expires "31-Dec-2020"    截止时间
    9、calendars "weekdays"
        timer (int:0 1h)    timer (cron:0 0 0/8 * * ?)
    
    循环控制
        10、Declared types
            declare SpecialOrder extends Order
                whatsSoSpecialAboutIt: String
                order: Order
                applicableDiscount: Discount
            end
        参考    chapter-04-tests    DeclaredTypesTest.java
        11、Property-reactive beans
            类似no-loop lock-on-active 的控制能力,可更细粒度,如只对某个或一些变量的变化进行关注或不关注
            参考    chapter-04-tests    PropertyReactiveTest.java
    特殊操作符
        12、正则表达式    
            when $c: Customer(email not matches "[A-Za-z0-9-.]+@[A-Za-z0-9-.]+$")
            then $c.setEmail(null); //invalidate email
        13、集合 contains 、 memberOf
            when
                $i: Item(name == "pencil")
                $ol: OrderLine(item == $i)
                $o: Order($ol memberOf orderLines,orderLines contains $ol)
            then ...
    14、from 字句    when
                Order(totalItems > 10, $c:customer)
                Coupon(customer == $c) from qServ.queryCoupons()
            then    ...
    15、Collect from objects    需要导入集合类,如 import java.util.List | Set
        加入有50个Order在session中,将会触发50次,因此可用该方式触发一次
        when
              $list: List() from collect(Order())  |  $list: List(size > 0) from collect(Order()) 收集到的结果数>0才触发
        then
              System.out.println("we've found " + $list.size() + " orders");
    16、accumulate 积累    条件表达式
        

        when
            $o: Order($lines: orderLines)            
            Number(intValue >= 10) from accumulate(  //String(toString contains '10') from accumulate(  可任意结果比较
                OrderLine(
                item.salePrice > 20.00, 
                $q: quantity
                ) from $lines,
                init(int count = 0;),
                action(count += $q;),
                reverse(count -= $q;),
                result(count)
                //或直接使用 sum($q)
            )
            then
            $o.increaseDiscount(0.05);
        init 初始化方法
        action 执行
        reverse (可选)
        result 结果
        也可直接使用以下函数:
        count: sum: avg: min: max: collectList: collectSet(对象不重复): 

        推荐直接使用函数
        when accumulate(Order($total: total),
            $maximum: max($total),
            $minimum: min($total),
            $average: avg($total)
            )
        then //...

        参考 chapter-04-tests    AccumulateTest.java
    17、关键字    
        not    not(Order() or Item()) 没有Order或Item则不触发
        exists    exists(Order())    exists这个关键字,与Order()的区别是:即使Order有多个,也只触发一次,同样 forall 
        forall    通常与 exists 联合使用作为预检查
            exists(Order())
            forall(
                Order()
                Order(orderLines.size() > 0)
            )
三、常用api

    KieSession kSession
    1、insert(Object obj)    
    2、getObjects(...)

四、架构
    
    1、环境加载
        例如加载classpath配置,通过 KieServices.newKieClasspathContainer(); 扫描加载配置,包括 kmodule.xml , ***.drl 等
    
    2、主要接口
        1)KieServices , 主要提供 创建 KieContainer 接口,如 KieServices.newKieClasspathContainer(); 创建classpath环境的 KieContainer 
        2)KieContainer ——* KieModule , 提供创建 KieSession 等主要接口
        3)KieModule 定义配置,可包含子KieModule
            <kbase name="rules.cp.discount">
                <ksession name="rules.cp.discount.session" type="stateful"/>
                </kbase>
        4)KieBase 定义在 KieModule 中 , 也提供创建 KieSession 接口
        5)KieSession 定义在 KieBase 中 , insert modify update 操纵接口 , stateful 可交互多次, stateless 只交互1次, 且需要用 
        StatelessKieSession statelessKieSession = kContainer.newStatelessKieSession("rules.simple.sl.discount");创建

五、最佳实践
    1、要避免条件引起的死循环,如 when $i:Item(cost < 200) then dosome....;update($i);//cost 还是 <200

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值