drools规则语言指南二在DRL中类型和元数据定义

4次阅读

共计 3720 个字符,预计需要花费 10 分钟才能阅读完成。

在 DRL 中类型和元数据定义

结构

类型声明结构:

元数据结构:

两种用途

  1. new 一个新的 fact
  2. 使用元数据 @key(value)这种方式,关联新的或已存在的 fact

不带有元数据的类型声明:

一个新 fact 的定义可以不需要元数据,但是必须要包含属性或者字段。
下面是在 DRL 中定义了一个新的 fact 类型 Person

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

Person 中有三个属性,_name_,_dateOfBirth_ 是 java 提供的类型 address 是我们自己定义的类型
为了避免使用全路径名,可以使用 import 语句导入进来, 如下:

import java.util.Date

declare Person
   name : String
   dateOfBirth : Date
   address : Address
end

原理:

当你在 drl 文件中定义了这样的一个类型时,drools engine 在编译的时候会生成如下的 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`
}

理解了这个,之后你就可以像使用普通的 fact 那样在规则中使用它:

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

DRL 中定义枚举类型:

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

从上面代码可以看出和 java 中极其相似

DRL 中类型继承

import org.people.Person

declare Person end

declare Student extends Person
    school : String
end

declare LongTermStudent extends Student
    years : int
    course : String
end

和 java 中的继承也基本一致

带有元数据的类型定义

元数据其实就是对数据做解释和下定义的数据。

import java.util.Date

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

    name : String @key @maxLength(30)
    dateOfBirth : Date
    address : Address
end

上面例子中的元数据 @author(Bob) 定义了这个类的作者是 BOb @dateOfCreation(01-Feb-2009) 定义了创建时间
@key 定义 name 作为构造函数的字段,@maxLength(30) 定义了这个字段的最大长度是 30
介绍一下下面的几个元数据标签:
先声明一个要使用的 java 类:

public class VoiceCall {
  private String  originNumber;
  private String  destinationNumber;
  private Date    callDateTime;
  private long    callDuration;  // in milliseconds

  // Constructors, getters, and setters
}
  1. @role: 定义这个 fact 是一个常规的 fact 还是一个 event(在 drools engine 复杂事件处理的时候),默认值是 fact
@role(fact | event)

声明为 event

declare VoiceCall
  @role(event)
end

@timestamp: 在 drools engine 中的每一个 event 时间字段,默认是 session 的时间
使用:

@timestamp(<attributeName>)

时间字段为 callDateTime

declare VoiceCall
  @role(event)
  @timestamp(callDateTime)
end

@duration

declare VoiceCall
  @role(event)
  @timestamp(callDateTime)
  @duration(callDuration)
end

@typesafe

declare VoiceCall
  @role(fact)
  @typesafe(false)
end

@serialVersionUID

declare VoiceCall
  @serialVersionUID(42)
end

@key重点讲一下这个

<attributeDefinition> @key

这个 @key主要是在构造函数那里使用例如:

declare Person
    firstName : String @key
    lastName : String @key
    age : int
end

生成的 java 类就会是这个样子:

Person() // Empty constructor

Person(String firstName, String lastName)

Person(String firstName, String lastName, int age)

实例化的时候:

Person person = new Person("John", "Doe");

@position:定义属性和参数的位置

<attributeDefinition> @position (<integer>)

例如:

declare Person
    firstName : String @position(1)
    lastName : String @position(0)
    age : int @position(2)
    occupation: String
end

那么实际上属性的位置就是按照如下顺序

lastName

firstName

age

occupation

这个在写规则源码的时候会非常重要,对应某个属性对应什么值

Person("Doe", "John", $a;)

Person("Doe", "John"; $a : age)

Person("Doe"; firstName == "John", $a : age)

Person(lastName == "Doe"; firstName == "John", $a : age)

在继承中如何生效:

declare Person
    firstName : String @position(1)
    lastName : String @position(0)
    age : int @position(2)
    occupation: String
end

declare Student extends Person
    degree : String @position(1)
    school : String @position(0)
    graduationDate : Date
end

实际的顺序就是:

lastName (position 0 in the parent type)

school (position 0 in the subtype)

firstName (position 1 in the parent type)

degree (position 1 in the subtype)

age (position 2 in the parent type)

occupation (first field with no position annotation)

graduationDate (second field with no position annotation)

更多解释参考官方文档:https://docs.jboss.org/drools…

正文完
 0