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