在DRL中类型和元数据定义
结构
类型声明结构:
元数据结构:
两种用途
- new一个新的fact
- 使用元数据@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
}
- @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...