当前位置:   article > 正文

drools学习笔记-DRL语法规则(一)_drools 规则函数

drools 规则函数

DRL(Drools规则语言)规则

DRL文件结构:

package

import

function  // Optional

query  // Optional

declare   // Optional

global   // Optional

rule "rule name"
    // Attributes
    when
        // Conditions
    then
        // Actions
end

rule "rule2 name"
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

package

和java的package概念类似,唯一的命名空间。一个规则库可以包含很多的package,但通常将一个package下的所有规则放在一个文件中。
drools提倡package和文件的路径相同。
package必须在rule文件的第一行,但是其他的内容的顺序可以变化。

import

引入其他package的对象。
格式:packageName.objectName

function

可以在rule文件中定义函数。
在规则下的then之中调用function。
也可以import其他package的function。
实例:

function String hello(String applicantName) {
    return "Hello " + applicantName + "!";
}

rule "Using a function"
  when
    // Empty
  then
    System.out.println( hello( "James" ) );
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
import function my.package.applicant.hello;

rule "Using a function"
  when
    // Empty
  then
    System.out.println( hello( "James" ) );
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

query

DRL文件中的Query在Drools引擎的工作内存中搜索与DRL文件中的规则相关的event。在DRL中定义Query,在java中调用query获得数据。
Query是全系统唯一的,必须保证在整个KIE中名称唯一。
实例:
DRL文件中的示例查询定义

query "people under the age of 21"
    $person : Person( age < 21 )
end
  • 1
  • 2
  • 3

获取查询结果的示例应用程序代码

QueryResults results = ksession.getQueryResults( "people under the age of 21" );
System.out.println( "we have " + results.size() + " people under the age  of 21" );
  • 1
  • 2

查询结果的遍历方式:

QueryResults results = ksession.getQueryResults( "people under the age of 21" );
System.out.println( "we have " + results.size() + " people under the age of 21" );

System.out.println( "These people are under the age of 21:" );

for ( QueryResultsRow row : results ) {
    Person person = ( Person ) row.get( "person" );
    System.out.println( person.getName() + "\n" );
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

位置参数

类型声明中声明的类型顺序与参数位置匹配。
如下实例,Location(x, y;)代替Location( thing == x, location == y):

declare Location
    thing : String
    location : String
end

query isContainedIn( String x, String y )
    Location(x, y;)
    or
    ( Location(z, y;) and ?isContainedIn(x, z;) )
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

主意:这里的“ z”将始终是“输出”变量。’?’ 符号表示查询仅是拉式查询。
可以使用@position重新定义顺序。

declare Cheese
    name : String @position(1)
    shop : String @position(2)
    price : int @position(0)
end
  • 1
  • 2
  • 3
  • 4
  • 5

org.drools.definition.type包中的@Position 可用于java的原始pojo。

DRL中的类型声明和元数据

DRL文件中的规则使用的event类型是新定义的类型或元数据:

  • 新的event model。默认为java.lang.Object.可以在drl中定义新的模型,不必在java中定义模型。
  • 元数据。

没有元数据的类型声明

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

每个属性的类型都可以是任何有效的Java类型,包括您创建的另一个类或先前声明的事实类型。为了避免在每次声明类时都写出全限定名,可以将全称定义为import子句的一部分:

import java.util.Date

declare Person
    name : String
    dateOfBirth : Date
    address : Address
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Drools引擎会在编译时生成declare的类型的Java类。上面的Person对应的java类为:

public class Person implements Serializable {
    private String name;
    private java.util.Date dateOfBirth;
    private Address address;

    // Empty constructor
    public Person() {...}

    // Constructor with all fields
    public Person( String name, Date dateOfBirth, Address address ) {...}

    // If keys are defined, constructor with keys
    public Person( ...keys... ) {...}

    // Getters and setters
    // `equals` and `hashCode`
    // `toString`
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在规则文件中就可以直接使用Person类型了,如下:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

DRL中的枚举类型声明

定义方式:

declare enum <factType>

declare enum DaysOfWeek
   SUN("Sunday"),MON("Monday"),TUE("Tuesday"),WED("Wednesday"),THU("Thursday"),FRI("Friday"),SAT("Saturday");

   fullName : String
end

rule "Using a declared Enum"
when
   $emp : Employee( dayOff == DaysOfWeek.MONDAY )
then
   ...
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

DRL中的扩展类型声明

也就是java中的继承。

import org.people.Person

declare Person end

declare Student extends Person
    school : String
end

declare LongTermStudent extends Student
    years : int
    course : String
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

DRL中带有元数据的类型声明

元数据可用于类型以及类型的属性。

import java.util.Date

declare Person
    @author( Bob )
    @dateOfCreation( 01-Feb-2009 )

    name : String @key @maxLength( 30 )
    dateOfBirth : Date
    address : Address
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以用于import的数据类型或者declare的数据类型:

import org.drools.examples.Person

declare Person
    @author( Bob )
    @dateOfCreation( 01-Feb-2009 )
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
declare org.drools.examples.Person
    @author( Bob )
    @dateOfCreation( 01-Feb-2009 )
end
  • 1
  • 2
  • 3
  • 4

元数据标签列表:

  • @role
    CEP中,给定的事实类型是作为常规事实还是在Drools引擎中的事件处理。
    默认参数: fact
    支持的参数:fact,event
    @role( fact | event )
declare VoiceCall
  @role( event )
end
  • 1
  • 2
  • 3
  • @timestamp
    每个event的时间戳
    默认参数:Drools引擎会话时钟增加的时间
    支持的参数:会话时钟时间或自定义时间戳属性
declare VoiceCall
  @role( event )
  @timestamp( callDateTime )
end
  • 1
  • 2
  • 3
  • 4
  • @duration
    事件可以是基于时间间隔的事件或时间点事件。基于时间间隔的事件具有持续时间,并持续存在于Drools引擎的工作存储器中,直到其持续时间过去。时间点事件没有持续时间,本质上是持续时间为零的基于间隔的事件。
declare VoiceCall
  @role( event )
  @timestamp( callDateTime )
  @duration( callDuration )
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • @expires
    该标签确定事件在Drools引擎的工作内存中到期之前的持续时间。默认情况下,当事件不再匹配并激活任何当前规则时,事件就会过期。该标签定义还覆盖了根据KIE基础中的时间约束和滑动窗口计算出的隐式过期偏移。
declare VoiceCall
  @role( event )
  @timestamp( callDateTime )
  @duration( callDuration )
  @expires( 1h35m )
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • @typesafe
  • @serialVersionUID
  • @key
    此标记使事实类型属性可用作事实类型的键标识符。
    生成的类可以实现equals()和hashCode()方法,以确定该类型的两个实例是否彼此相等。Drools引擎还可以使用所有关键属性作为参数来生成构造函数。
declare Person
    firstName : String @key
    lastName : String @key
    age : int
end
  • 1
  • 2
  • 3
  • 4
  • 5

对于此示例,Drools引擎检查firstName和lastName属性以确定两个的实例是否Person彼此相等,但不检查该age属性。Drools引擎还隐式生成了三个构造函数:一个没有参数,一个带有@key字段,一个带有所有字段的构造器:

Person() // Empty constructor

Person( String firstName, String lastName )

Person( String firstName, String lastName, int age )
  • 1
  • 2
  • 3
  • 4
  • 5
  • @position
    此标记确定声明的事实类型属性或字段在位置参数中的位置,从而覆盖属性的默认声明顺序。您可以使用此标记来修改模式中的位置约束,同时在类型声明和位置参数中保持一致的格式。
declare Person
    firstName : String @position( 1 )
    lastName : String @position( 0 )
    age : int @position( 2 )
    occupation: String
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在此示例中,按以下顺序在位置参数中对属性进行优先级排序:
1 lastName
2 firstName
3 age
4 occupation
在位置参数中,无需指定字段名称,因为位置映射到已知的命名字段。例如,参数Person( lastName == “Doe” )与相同Person( “Doe”

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/798473
推荐阅读
相关标签