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

在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(  )

时间字段为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重点讲一下这个

 @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 :定义属性和参数的位置

 @position (  )

例如:

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...

你可能感兴趣的