规则引擎-drools-3.1-drl文件构成 global、function、query等

drl文件构成

drl文件构成,位于官网的第5章位置,也是drools作为规则引擎应用的最核心部分。

  1. Rule Language Reference
    官网链接:https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html#_droolslanguagereferencechapter

在这里插入图片描述
其中,package、rule end,是必须的,一般情况下import也少不了。
global、function、query则不是文件的必须项。

各模块解说

package

import

global   // Optional

function  // Optional

query  // Optional

declare   // Optional

rule "rule name"
    // Attributes 属性
    when
        // Conditions 条件
    then
        // Actions 结果
end

rule "rule2 name"

...

package

类似于java类中的package,当drl文件存放的路径与drl文件中的package定义不同时,
例如drl文件存放路径为 resources/order,而drl文件中的package定义的是 rules

package rules;

使用kieheaper时,会报警告:
WARN 18656 — [nio-9531-exec-2] o.d.c.kie.builder.impl.KieBuilderImpl : File ‘order.drl’ is in folder "order’’ but declares package ‘rules’. It is advised to have a correspondance between package and folder names.

import

类似于java类中的import,可以引用java类,此时用法与java代码中的import一致,也可以引用静态方法,这点和java代码有区别。示例代码:

import java.util.Map
import com.dcy.drools.entity.Order
import com.dcy.drools.entity.Customer

global

全局变量,global定义的变量,可以在jvm内存和drools工作内存中进行共享。具体是kiesession会话与它的外部环境进行打通。
举例:
drl文件:

package rules;
import java.util.List;

global java.util.List myGlobalList;

rule "rule-g-1"
    when
    then
        myGlobalList.add("rule-g-1");
        System.out.println("global-rule-g-1。。");
end

test方法:

@Test
    public void testGlobal() {
        // 获取services
        KieServices kieServices = KieServices.Factory.get();
        // 获取container
        KieContainer container = kieServices.getKieClasspathContainer();
        // 获取session
        KieSession kieSession = container.newKieSession();

        List<String> list = new ArrayList<>();
        list.add("testGlobal");
        kieSession.setGlobal("myGlobalList", list);
        // 触发规则
        kieSession.fireAllRules();
        kieSession.dispose();

        System.out.println("global list:" + list);
    }

执行输出结果:

global-rule-g-1。。
global list:[testGlobal, rule-g-1]

function

类似于java类中的私有方法,function只能在drl当前文件内调用,算是一种“私有”方法。

**function String format(String username) {
    return "hello " + username;
}**

rule "Using a function"
  when
    // Empty
  then
    System.out.println( **format**( "James" ) );
end

query

和规则的区别是:规则是匹配到了条件之后,执行then后面的代码,query匹配到了之后将匹配到的fact对象返回到一个结果集,通过kie可以获取。也可以在rule中使用。
query可以有入参也可以无入参。

// 无入参的query  query_1 也可以使用string,如"query-1"
query query_1
    $person:Person(age > 30)
end
// 有入参的query
query query_2 (String username)
    $person:Person(age > 30, username == name)
end

kie使用query得到满足条件的集合

@Test
    public void testPerson() {
        // 获取services
        KieServices kieServices = KieServices.Factory.get();
        // 获取container
        KieContainer container = kieServices.getKieClasspathContainer();
        // 获取session
        KieSession kieSession = container.newKieSession();

        Person p1 = new Person();
        p1.setAge(33);
        p1.setName("zhang san");

        Person p2 = new Person();
        p2.setAge(40);
        p2.setName("li san");

        kieSession.insert(p1);
        kieSession.insert(p2);

        // 执行查询
        QueryResults query1 = kieSession.getQueryResults("query_1");
        Iterator<QueryResultsRow> iterator = query1.iterator();
        System.out.println("符合query-1查询结果如下:");
        while (iterator.hasNext()) {
            QueryResultsRow row = iterator.next();
            Person person = (Person) row.get("$person");
            System.out.println(person.getName());
        }

        QueryResults query2 = kieSession.getQueryResults("query_2", "li san");
        Iterator<QueryResultsRow> iterator2 = query2.iterator();
        System.out.println("符合query-2查询结果如下:");
        while (iterator2.hasNext()) {
            QueryResultsRow row = iterator2.next();
            Person person = (Person) row.get("$person");
            System.out.println(person.getName());
        }

        kieSession.dispose();
    }

输出结果:

符合query-1查询结果如下:
zhang san
li san
符合query-2查询结果如下:
li san

在rule中使用query

rule "user query"
when
    $person:Person(age > 30)
    query_2("li san";)
then
    System.out.println("在rule中使用query");
end

declare

declare 声明一个新类型,你所做的事是使用关键字 declare,紧接着是字段列表,和关键字 end
和java的定义类使用方法类似,且可以使用extends实现继承。
可以定义新类型(类似java的class)
也可以定义元数据

直接使用官网例子,实际使用中,不多用

declare Person
  name : String
  dateOfBirth : java.util.Date
  address : Address
end

rule "Using a declared type"
  when
    $p : Person( name == "James" )
  then   // Insert Mark, who is a customer of James.
    Person mark = new Person();
    mark.setName( "Mark" );
    insert( mark );
end

rule相关

鉴于篇幅问题,关于这部分,需要另起文章来总结了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值