轉載請註明出處:http://blog.csdn.net/luonanqin
Esper對事件有特殊的數據結構約定。能處理的事件結構有:POJO,java.util.Map,Object Array,XML
1.POJO
對於POJO,Esper要求對每一個私有屬性要有getter方法。Esper允許不必按照JavaBean規定的格式,但是getter方法是必須的。又或者可以在配置文件中配置可訪問的方法來代替getter。簡單示例如下
public class Person
{
String name;
int age;
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
Esper同樣也能支持複雜的數據類型以及嵌套。稍微複雜的Person如下
import java.util.List;
import java.util.Map;
public class Person
{
String name;
int age;
List<Child> children;
Map<String, Integer> phones;
Address address;
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public List<Child> getChildren()
{
return children;
}
public Map<String, Integer> getPhones()
{
return phones;
}
public Address getAddress()
{
return address;
}
}
class Child
{
String name;
int gender;
// 省略getter方法
}
class Address
{
String road;
String street;
int houseNo;
// 省略getter方法
}
如上所示,Esper能支持包含了集合類型和嵌套類的POJO,示例的EPL語句如下
// 當Person類型的事件中name爲luonanqin時,Esper能得到對應的age,children和address
select age,children,address from Person where name="luonanqin"
如果我不想要所有的child,而是想要第二個。並且我想得到家裏的電話號碼,那麼Person需要改動一下
import java.util.List;
import java.util.Map;
public class Person
{
String name;
int age;
List<Child> children;
Map<String, Integer> phones;
Address address;
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public Child getChildren(int index)
{
return children.get(index);
}
public int getPhones(String name)
{
return phones.get(name);
}
public Address getAddress()
{
return address;
}
// Address,Child不變
}
對應的EPL如下
// 當Person類型的事件中name爲luonanqin時,Esper能得到對應的第二個孩子,家裏的電話和家庭住址在哪條路上
select children[1], phones('home'), address.road where Person where name="luonanqin"
Esper支持事件的更新,對此Esper要求提供對應的setter方法。Person需要再有點小該度。示例如下
import java.util.List;
import java.util.Map;
public class Person
{
String name;
int age;
List<Child> children;
Map<String, Integer> phones;
Address address;
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public Child getChildren(int index)
{
return children.get(index);
}
// 此方法用於phones屬性的更新
public void setPhones(String name, Integer number){
phones.put(name, number);
}
public int getPhones(String name)
{
return phones.get(name);
}
public Address getAddress()
{
return address;
}
// Address,Child不變
}
對應的EPL如下
// 當Person類型的事件中name爲luonanqin時,更新家裏的電話
update Person set phones('home') = 123456789 where name="luonanqin"
Esper對POJO的支持基本上就是上面所說的,另外他還支持實現了多個接口類或者抽象類的POJO,使用方法和普通的POJO沒什麼區別,這裏就不列舉了。
2.Map
Esper支持原生Java Map結構的事件。相對於POJO來說,Map的結構更利於事件類型的熱加載,畢竟不是class,所以不需要重啓JVM。所以如果系統對重啓比較敏感,建議使用Map來定義事件的結構。Map的結構很簡單,主要分爲事件定義名和事件屬性列表。我們繼續拿Person來講解
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.espertech.esper.client.EPAdministrator;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
public class PersonMap
{
public static void main(String[] args)
{
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPAdministrator admin = epService.getEPAdministrator();
// Person定義
Map<String,Object> person = new HashMap<String,Object>();
person.put("name", String.class);
person.put("age", int.class);
person.put("children", List.class);
person.put("phones", Map.class);
// 註冊Person到Esper
admin.getConfiguration().addEventType("Person", person);
}
}
如上所示,Map結構的事件需要將屬性名作爲key,屬性的數據類型作爲value保存到Map中,然後再通過Esper的接口註冊到Esper。其中addEventType的兩個參數分別代表事件定義的名稱和所定義的結構。
對應的EPL和POJO的沒有區別
// 當Person類型的事件中name爲luonanqin時,Esper能得到對應的age,children
select age,children from Person where name="luonanqin"
Map對於嵌套類的定義比較特別。如果嵌套的類是POJO,那就如上面所示。如果嵌套的還是Map,那麼定義方式就需要改變。我們爲Person加上Address,示例如下
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.espertech.esper.client.EPAdministrator;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
public class PersonMap
{
public static void main(String[] args)
{
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPAdministrator admin = epService.getEPAdministrator();
// Address定義
Map<String, Object> address = new HashMap<String, Object>();
address.put("road", String.class);
address.put("street", String.class);
address.put("houseNo", int.class);
// Person定義
Map<String, Object> person = new HashMap<String, Object>();
person.put("name", String.class);
person.put("age", int.class);
person.put("children", List.class);
person.put("phones", Map.class);
person.put("address", "Address");
// 註冊Address到Esper
admin.getConfiguration().addEventType("Address", address);
// 註冊Person到Esper
admin.getConfiguration().addEventType("Person", person);
}
}
如上所示,有兩個關鍵點:
1.Person在定義Address屬性時,map的value不是Address.class,而是Address字符串,而這就代表引擎裏的Address對應的Map結構定義
2.事件定義註冊必須是Address先於Person,因爲Person用到了Address,而引擎是根據Address註冊時用的名字去查找Address定義的,所以如果名字寫錯,引擎就找不到Address了
如果Person有多個Address,則以數組方式定義Person的多個Address時,代碼又變成下面的樣子了
person.put("addresses", "Address[]");
另外對於Map,Esper只支持增量更新,也就是說只能增加Map中的屬性定義,而不能修改或者刪除某個屬性(實際上屬性增多並不影響其處理性能,所以沒有刪除在我看來也沒什麼。至於修改,也只能是先註銷再註冊了)。我們爲Person增加一個gender屬性,示例如下
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.espertech.esper.client.EPAdministrator;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EventType;
public class PersonMap
{
public static void main(String[] args)
{
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPAdministrator admin = epService.getEPAdministrator();
// Address定義
Map<String, Object> address = new HashMap<String, Object>();
address.put("road", String.class);
address.put("street", String.class);
address.put("houseNo", int.class);
// Person定義
Map<String, Object> person = new HashMap<String, Object>();
person.put("name", String.class);
person.put("age", int.class);
person.put("children", List.class);
person.put("phones", Map.class);
person.put("address", "Address");
// 註冊Address到Esper
admin.getConfiguration().addEventType("Address", address);
// 註冊Person到Esper
admin.getConfiguration().addEventType("Person", person);
// 新增一個gender屬性
person.put("gender", int.class);
admin.getConfiguration().updateMapEventType("Person", person);
/** 輸出結果:
* Person props: [address, age, name, children, phones, gender]
*/
EventType event = admin.getConfiguration().getEventType("Person");
System.out.println("Person props: " + Arrays.asList(event.getPropertyNames()));
}
}
3.Object Array
對象數組和Map很像,基本沒有差別。只是定義方式不一樣,Esper同樣也只支持增量更新。這裏繼續用Person爲大家做例子
import java.util.Arrays;
import java.util.Map;
import com.espertech.esper.client.EPAdministrator;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EventType;
public class PersonArray
{
/**
* @param args
*/
public static void main(String[] args)
{
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPAdministrator admin = epService.getEPAdministrator();
// Address定義
String[] addressPropNames = { "road", "street", "houseNo" };
Object[] addressPropTypes = { String.class, String.class, int.class };
// Child定義
String[] childPropNames = { "name", "age" };
Object[] childPropTypes = { String.class, int.class };
// Person定義
String[] personPropNames = { "name", "age", "children", "phones", "address" };
Object[] personPropTypes = { String.class, int.class, "Child[]", Map.class, "Address" };
// 註冊Address到Esper
admin.getConfiguration().addEventType("Address", addressPropNames, addressPropTypes);
// 註冊Child到Esper
admin.getConfiguration().addEventType("Child", childPropNames, childPropTypes);
// 註冊Person到Esper
admin.getConfiguration().addEventType("Person", personPropNames, personPropTypes);
// 新增一個gender屬性
admin.getConfiguration().updateObjectArrayEventType("Person", new String[] { "gender" }, new Object[] { int.class });
/** 輸出結果:
* Person props: [name, age, children, phones, address, gender]
*/
EventType event = admin.getConfiguration().getEventType("Person");
System.out.println("Person props: " + Arrays.asList(event.getPropertyNames()));
}
}
上面的例子包含了對象數組這種事件格式的所有特性,我就不多加解釋了。4.XML
很抱歉我沒有實際研究過XML,所以這一節就先不寫了,免得誤導大家就不好了。假以時日我研究之後,一定會把這節補上的。各位請見諒!!
上面列出的4種事件格式,在實際的應用過程中,對於其對應的事件數據,發送到引擎的方式有點區別。下一篇將會說到這一點,並且有比較新奇的東西哦,你會瞬間感受到Esper的魅力所在。敬請關注