欢迎转载学习,但转载须注明出处:http://blog.csdn.net/minimicall,尊重劳动成果,版权归我。
这一节中我们继续学习Esper的事件部分内容。
对应官方的文档为2.4-2.5
2.4 碎片及碎片类型(Fragment and Fragment Type)
有些情况,一个事件的某个属性本身又是一个事件。Esper对这种称作为fragment(碎片)和碎片类型。一个示例就是,两个或者更多的事件可以组成和一个新的事件作为输出,而这个输出事件在将来可能又作为其他事件的一个碎片属性。
碎片及类型属性使得你可以组合事件,而无需使用Java 反射API,这减少了事件底层操作处理。相关API见15.6,“Event and Event Type”
2.5 POJO事件(Plain-Old Java Object)
POJO是指类对象通过像JavaBean风格的方法提供getter方法向外界开放内部属性。这种事件类,也不是完全需要严格遵循JavaBean的约定,但一定要提供getter方法,或者是通过某种配置达到目的。
Esper支持JavaBean风格的事件类,它可以是某个基类的扩展,或者是一个或者多个接口的实现。Esper的时间模式和EPL语句也支持指向Java接口类和抽象类。
代表事件的类应该是不可变的。因为事件代表的是过去发生的动作或者状态的改变,所以应该是不能改变的。但这也不是严格要求,Esper引擎也接受可变的事件。
事件类的hashCode和equals方法无需实现。其实现也不会影响Esper引擎的工作表现。
2.5.1 Java Object Event Properties(Java对象事件属性)
前面我们提到,我们支持遵循标准JavaBean约定的属性类型,斌企鹅有一些是Esper特定支持的:
1) Simple 简单属性仅仅包含一个单一的可检索的值。属性的底层实现可能是Java语言的内置类型(例如int,简单对象java.lang.String)或更为复杂的对象,它可能是由Java语言定义的、或者是应用定义的,或是第三方库定义的。
2) Indexed 索引属性存储的是同一类型的有序对象容器,容器内的对象可以通过索引单独访问。
3) Mapped JavaBean API的扩展,Esper考虑任何由以String类型作为key的映射属性。
4) Nested 嵌套属性是指该属性所在的对象是一个事件的一个属性。即它是事件属性的属性。
假如这里有个NewEmployeeEvent事件类。这里的索引和映射属性返回的是Java对象,但也可以返回Java的内置类型(例如int和String)。Address对象和Employee对象都可以嵌套它们自己的属性,例如Address里面可以有街道名称,Employee中可以有雇员姓名。
public classNewEmployeeEvent {
public StringgetFirstName();
public AddressgetAddress(String type);
public EmployeegetSubordinate(int index);
public Employee[]getAllSubordinates();
}
简单事件属性需要一个getter方法,用于返回属性值。在这个例子中,getFirstName方法返回firstName事件属性,它为String类型。
索引事件属性需要如下的两种getter方法的至少一种。第一种,以整形为参数返回一个属性值,例如getSuborinate方法;另一种方法是返回整个数组对象,例如getAllSubordinates方法。在EPL或者事件模式语句中,索引属性通过property[index]来访问。
映射事件属性需要一个getter方法,它以String类型的关键字作为参数,返回属性值,例如getAddress方法。在EPL或者事件模式语句中,映射属性通过property(‘key’)来访问。
嵌套事件属性需要一个getter方法用于返回嵌套对象。getAddress和getSubordinate是映射和索引属性,它们返回的是一个嵌套对象。在EPL和事件模式语句中,嵌套属性通过property.nestedProperty来访问。
上述的这些属性可以任意的进行复合。例如下面就是这些属性的一些复合示例:
everyNewEmployeeEvent(firstName='myName')
everyNewEmployeeEvent(address('home').streetName='Park Avenue')
everyNewEmployeeEvent(subordinate[0].name='anotherName')
everyNewEmployeeEvent(allSubordinates[1].name='thatName')
everyNewEmployeeEvent(subordinate[0].address('home').streetName='Water Street')
类似的,这些语法可以应用在EPL语句任何事件属性名可以出现的地方,例如select列表,where语句,jion语句等。
select firstName,address('work'), subordinate[0].name, subordinate[1].name
from NewEmployeeEvent
whereaddress('work').streetName = 'Park Ave'
2.5.2 属性名
属性名遵循Java标准:java.beans.Introspector类和getBeanInfo方法返回属性名。此外,Esper还可以通过配置一个标识来关闭大小写敏感,表2.4是属性名和相应getter方法的示例。
方法 属性名 示例
getPrice()
Price Select pricefrom myEvent
getNAME()
NAME Select NAME frommyEvent
getItemDesc()
itemDesc
Select itemDesc frommyEvent
getQ() Q Select qfrom myEvent
getQN() QN Select QNfrom myEvent
getqn() qn Select qnfrom myEvent
gets() s Select sfrom myEvent
2.5.3 参数化类型
当你的getter方法的到的是一个参数化的类型,例如索引属性,Iterable<MyEventData>,映射属性Map<String,MyEventData>,那么这个参数化类型就是指向属性的属性表达式,它可以获得属性值。
public classNewEmployeeEvent {
public StringgetName();
public Iterable<EducationHistory>getEducation();
publicMap<String, Address> getAddresses();
}
一个获得属性的表达式如下:
select name,education, education[0].date, addresses('home').street
from NewEmployeeEvent
2.5.4 索引和映射属性的setter方法
EPL语句可以更新事件的索引和映射属性,提供了设置属性的setter方法。
索引属性的setter方法必须形如setPropertyName,并且有两个参数,整形的索引参数和Object类型的属性新值。
映射属性的setter方法,必须是形如setPropertyName,并且接受两个参数,String类型的关键字和Object类型的属性值。
下面就是设置事件索引和映射属性的一个示例:
public class MyEvent{
private Mapprops = new HashMap();
privateObject[] array = new Object[10];
public voidsetProps(String name, Object value) {
props.put(name, value);
}
public voidsetArray(int index, Object value) {
array[index] = value;
}
// ... alsoprovide regular JavaBean getters and setters for all properties
下面语句是设置索引和映射属性:
update istreamMyEventStream set props('key') = 'abc', array[2] = 100
2.5.5 已知的局限性
Esper是获得事件属性的字节码,当字节码获取失败时,这时候引擎会记录一个警告并使用java反射机制去获得属性值。
一个已知的局限性是,当想获得一个属性值,但真实获得的却是属性值子类的对象,引擎就会告警。