上周我们介绍了Esper,它是一个适合实时分析数据的内存计算引擎。若有不了解的同学可以看一下 Esper学习之一:Esper介绍。如果各位自己运行过之前的程序,应该对Esper的处理机制和EPL比较感兴趣。不过这篇文章就先来介绍一下Esper能处理的数据结构,即“事件”。

Esper对事件有特殊的数据结构约定。能处理的事件结构有:POJO,java.util.Map,Object Array,XML

1.POJO

对于POJO,Esper要求对每一个私有属性要有getter方法。Esper允许不必按照JavaBean规定的格式,但是getter方法是必须的。又或者可以在配置文件中配置可访问的方法来代替getter。简单示例如下

[java] view plaincopyprint?
  1. public class Person
  2. {
  3. String name;
  4. int age;
  5. public String getName()
  6. {
  7. return name;
  8. }
  9. public int getAge()
  10. {
  11. return age;
  12. }
  13. }
public class Person
{String name;int age;public String getName(){return name;}public int getAge(){return age;}
}

Esper同样也能支持复杂的数据类型以及嵌套。稍微复杂的Person如下

[java] view plaincopyprint?
  1. import java.util.List;
  2. import java.util.Map;
  3. public class Person
  4. {
  5. String name;
  6. int age;
  7. List<Child> children;
  8. Map<String, Integer> phones;
  9. Address address;
  10. public String getName()
  11. {
  12. return name;
  13. }
  14. public int getAge()
  15. {
  16. return age;
  17. }
  18. public List<Child> getChildren()
  19. {
  20. return children;
  21. }
  22. public Map<String, Integer> getPhones()
  23. {
  24. return phones;
  25. }
  26. public Address getAddress()
  27. {
  28. return address;
  29. }
  30. }
  31. class Child
  32. {
  33. String name;
  34. int gender;
  35. // 省略getter方法
  36. }
  37. class Address
  38. {
  39. String road;
  40. String street;
  41. int houseNo;
  42. // 省略getter方法
  43. }
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语句如下

[sql] view plaincopyprint?
  1. // 当Person类型的事件中name为luonanqin时,Esper能得到对应的age,children和address
  2. select age,children,address from Person where name="luonanqin"
// 当Person类型的事件中name为luonanqin时,Esper能得到对应的age,children和address
select age,children,address from Person where name="luonanqin"

如果我不想要所有的child,而是想要第二个。并且我想得到家里的电话号码,那么Person需要改动一下

[java] view plaincopyprint?
  1. import java.util.List;
  2. import java.util.Map;
  3. public class Person
  4. {
  5. String name;
  6. int age;
  7. List<Child> children;
  8. Map<String, Integer> phones;
  9. Address address;
  10. public String getName()
  11. {
  12. return name;
  13. }
  14. public int getAge()
  15. {
  16. return age;
  17. }
  18. public Child getChildren(int index)
  19. {
  20. return children.get(index);
  21. }
  22. public int getPhones(String name)
  23. {
  24. return phones.get(name);
  25. }
  26. public Address getAddress()
  27. {
  28. return address;
  29. }
  30. // Address,Child不变
  31. }
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如下

[java] view plaincopyprint?
  1. // 当Person类型的事件中name为luonanqin时,Esper能得到对应的第二个孩子,家里的电话和家庭住址在哪条路上
  2. select children[1], phones('home'), address.road where Person where name="luonanqin"
// 当Person类型的事件中name为luonanqin时,Esper能得到对应的第二个孩子,家里的电话和家庭住址在哪条路上
select children[1], phones('home'), address.road where Person where name="luonanqin"

Esper支持事件的更新,对此Esper要求提供对应的setter方法。Person需要再有点小该度。示例如下

[java] view plaincopyprint?
  1. import java.util.List;
  2. import java.util.Map;
  3. public class Person
  4. {
  5. String name;
  6. int age;
  7. List<Child> children;
  8. Map<String, Integer> phones;
  9. Address address;
  10. public String getName()
  11. {
  12. return name;
  13. }
  14. public int getAge()
  15. {
  16. return age;
  17. }
  18. public Child getChildren(int index)
  19. {
  20. return children.get(index);
  21. }
  22. // 此方法用于phones属性的更新
  23. public void setPhones(String name, Integer number){
  24. phones.put(name, number);
  25. }
  26. public int getPhones(String name)
  27. {
  28. return phones.get(name);
  29. }
  30. public Address getAddress()
  31. {
  32. return address;
  33. }
  34. // Address,Child不变
  35. }
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如下

[sql] view plaincopyprint?
  1. // 当Person类型的事件中name为luonanqin时,更新家里的电话
  2. update Person set phones('home') = 123456789 where name="luonanqin"
// 当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来讲解

[java] view plaincopyprint?
  1. import java.util.HashMap;
  2. import java.util.List;
  3. import java.util.Map;
  4. import com.espertech.esper.client.EPAdministrator;
  5. import com.espertech.esper.client.EPServiceProvider;
  6. import com.espertech.esper.client.EPServiceProviderManager;
  7. public class PersonMap
  8. {
  9. public static void main(String[] args)
  10. {
  11. EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
  12. EPAdministrator admin = epService.getEPAdministrator();
  13. // Person定义
  14. Map<String,Object> person = new HashMap<String,Object>();
  15. person.put("name", String.class);
  16. person.put("age", int.class);
  17. person.put("children", List.class);
  18. person.put("phones", Map.class);
  19. // 注册Person到Esper
  20. admin.getConfiguration().addEventType("Person", person);
  21. }
  22. }
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到Esperadmin.getConfiguration().addEventType("Person", person);}
}

如上所示,Map结构的事件需要将属性名作为key,属性的数据类型作为value保存到Map中,然后再通过Esper的接口注册到Esper。其中addEventType的两个参数分别代表事件定义的名称和所定义的结构。

对应的EPL和POJO的没有区别

[sql] view plaincopyprint?
  1. // 当Person类型的事件中name为luonanqin时,Esper能得到对应的age,children
  2. select age,children from Person where name="luonanqin"
// 当Person类型的事件中name为luonanqin时,Esper能得到对应的age,children
select age,children from Person where name="luonanqin"

Map对于嵌套类的定义比较特别。如果嵌套的类是POJO,那就如上面所示。如果嵌套的还是Map,那么定义方式就需要改变。我们为Person加上Address,示例如下

[java] view plaincopyprint?
  1. import java.util.HashMap;
  2. import java.util.List;
  3. import java.util.Map;
  4. import com.espertech.esper.client.EPAdministrator;
  5. import com.espertech.esper.client.EPServiceProvider;
  6. import com.espertech.esper.client.EPServiceProviderManager;
  7. public class PersonMap
  8. {
  9. public static void main(String[] args)
  10. {
  11. EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
  12. EPAdministrator admin = epService.getEPAdministrator();
  13. // Address定义
  14. Map<String, Object> address = new HashMap<String, Object>();
  15. address.put("road", String.class);
  16. address.put("street", String.class);
  17. address.put("houseNo", int.class);
  18. // Person定义
  19. Map<String, Object> person = new HashMap<String, Object>();
  20. person.put("name", String.class);
  21. person.put("age", int.class);
  22. person.put("children", List.class);
  23. person.put("phones", Map.class);
  24. person.put("address", "Address");
  25. // 注册Address到Esper
  26. admin.getConfiguration().addEventType("Address", address);
  27. // 注册Person到Esper
  28. admin.getConfiguration().addEventType("Person", person);
  29. }
  30. }
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到Esperadmin.getConfiguration().addEventType("Address", address);// 注册Person到Esperadmin.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时,代码又变成下面的样子了

[java] view plaincopyprint?
  1. person.put("addresses", "Address[]");
person.put("addresses", "Address[]");

另外对于Map,Esper只支持增量更新,也就是说只能增加Map中的属性定义,而不能修改或者删除某个属性(实际上属性增多并不影响其处理性能,所以没有删除在我看来也没什么。至于修改,也只能是先注销再注册了)。我们为Person增加一个gender属性,示例如下

[java] view plaincopyprint?
  1. import java.util.Arrays;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import com.espertech.esper.client.EPAdministrator;
  6. import com.espertech.esper.client.EPServiceProvider;
  7. import com.espertech.esper.client.EPServiceProviderManager;
  8. import com.espertech.esper.client.EventType;
  9. public class PersonMap
  10. {
  11. public static void main(String[] args)
  12. {
  13. EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
  14. EPAdministrator admin = epService.getEPAdministrator();
  15. // Address定义
  16. Map<String, Object> address = new HashMap<String, Object>();
  17. address.put("road", String.class);
  18. address.put("street", String.class);
  19. address.put("houseNo", int.class);
  20. // Person定义
  21. Map<String, Object> person = new HashMap<String, Object>();
  22. person.put("name", String.class);
  23. person.put("age", int.class);
  24. person.put("children", List.class);
  25. person.put("phones", Map.class);
  26. person.put("address", "Address");
  27. // 注册Address到Esper
  28. admin.getConfiguration().addEventType("Address", address);
  29. // 注册Person到Esper
  30. admin.getConfiguration().addEventType("Person", person);
  31. // 新增一个gender属性
  32. person.put("gender", int.class);
  33. admin.getConfiguration().updateMapEventType("Person", person);
  34. /** 输出结果:
  35. * Person props: [address, age, name, children, phones, gender]
  36. */
  37. EventType event = admin.getConfiguration().getEventType("Person");
  38. System.out.println("Person props: " + Arrays.asList(event.getPropertyNames()));
  39. }
  40. }
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到Esperadmin.getConfiguration().addEventType("Address", address);// 注册Person到Esperadmin.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为大家做例子

[java] view plaincopyprint?
  1. import java.util.Arrays;
  2. import java.util.Map;
  3. import com.espertech.esper.client.EPAdministrator;
  4. import com.espertech.esper.client.EPServiceProvider;
  5. import com.espertech.esper.client.EPServiceProviderManager;
  6. import com.espertech.esper.client.EventType;
  7. public class PersonArray
  8. {
  9. /**
  10. * @param args
  11. */
  12. public static void main(String[] args)
  13. {
  14. EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
  15. EPAdministrator admin = epService.getEPAdministrator();
  16. // Address定义
  17. String[] addressPropNames = { "road", "street", "houseNo" };
  18. Object[] addressPropTypes = { String.class, String.class, int.class };
  19. // Child定义
  20. String[] childPropNames = { "name", "age" };
  21. Object[] childPropTypes = { String.class, int.class };
  22. // Person定义
  23. String[] personPropNames = { "name", "age", "children", "phones", "address" };
  24. Object[] personPropTypes = { String.class, int.class, "Child[]", Map.class, "Address" };
  25. // 注册Address到Esper
  26. admin.getConfiguration().addEventType("Address", addressPropNames, addressPropTypes);
  27. // 注册Child到Esper
  28. admin.getConfiguration().addEventType("Child", childPropNames, childPropTypes);
  29. // 注册Person到Esper
  30. admin.getConfiguration().addEventType("Person", personPropNames, personPropTypes);
  31. // 新增一个gender属性
  32. admin.getConfiguration().updateObjectArrayEventType("Person", new String[] { "gender" }, new Object[] { int.class });
  33. /** 输出结果:
  34. * Person props: [name, age, children, phones, address, gender]
  35. */
  36. EventType event = admin.getConfiguration().getEventType("Person");
  37. System.out.println("Person props: " + Arrays.asList(event.getPropertyNames()));
  38. }
  39. }
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到Esperadmin.getConfiguration().addEventType("Address", addressPropNames, addressPropTypes);// 注册Child到Esperadmin.getConfiguration().addEventType("Child", childPropNames, childPropTypes);// 注册Person到Esperadmin.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的魅力所在。敬请关注

Esper学习之二:事件类型 .相关推荐

  1. C++11/14学习(二)类型推导

    C++11/14学习(二)类型推导 C++11 引入了 auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型. 这使得 C++ 也具有了和其他现代编程语言一样,某种意义 ...

  2. 初探swift语言的学习笔记二(可选类型?和隐式可选类型!)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/28904115 转载请注明出处 如果觉得文章对你有所帮助,请通过留言 ...

  3. Vue3学习笔记(二)——事件按键表单修饰符与表单

    点击查看上一篇文章

  4. Esper学习之三:进程模型 .

    之前对Esper所能处理的事件结构进行了概述,并结合了例子进行讲解,不清楚的同学请看Esper学习之二:事件类型.今天主要为大家解释一下Esper是怎么处理事件的,即Esper的进程模型. 1.Upd ...

  5. Esper学习之十二:EPL语法(八)

    今天的内容十分重要,在Esper的应用中是十分常用的功能之一.它是一种事件集合,我们可以对这个集合进行增删查改,所以在复杂的业务场景中我们肯定不会缺少它.它就是Named Window. 由于本篇篇幅 ...

  6. [读书笔记]C#学习笔记二: 委托和事件的用法及不同.

    前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针 ...

  7. Esper——事件类型

    http://blog.csdn.net/luonanqin 上周我们介绍了Esper,它是一个适合实时分析数据的内存计算引擎.若有不了解的同学可以看一下 Esper学习之一:Esper介绍.如果各位 ...

  8. JavaScript学习(二十九)—JS常用的事件

    JavaScript学习(二十九)-JS常用的事件 一.页面相关事件 onload事件:当页面中所有的标签都加载完成后厨房该事件,格式:window.onload <body><sc ...

  9. JavaScript学习(二十八)—事件冒泡和事件捕获

    JavaScript学习(二十八)-事件冒泡和事件捕获 一.什么是事件流? 简单说,事件流就是指事件的执行顺序,他包含两种模式:事件冒泡.事件捕获. (一).事件冒泡 最常用的一种模式,就是指事件的执 ...

最新文章

  1. Python --金字塔
  2. 【小松教你手游开发】【unity实用技能】给每个GameObject的打开关闭加上一个渐变...
  3. MySQL工作笔记-检索出某一时间段中的数据,并更新
  4. linux内核模块和功能,我可以用模块替换Linux内核功能吗?
  5. 卖完砖头的Supreme要卖手机了 这种手机就不要讨论配置了吧...
  6. vue父子组件搭配(添加数据和删除)
  7. 常见危险函数和特殊函数(二)----变量覆盖
  8. Eclipse代码自动补全设置
  9. 「代码随想录」本周学习小结!(动态规划系列四)
  10. PHP教程,PHP入门教程大全(2021整理)
  11. 【考研经验】2018复旦计算机专硕零基础学渣考研经验贴
  12. 医院护理管理系统方案/案列/软件/小程序/APP/网站
  13. Salesforce基础名词
  14. loss 加权_样本生而不等——聊聊那些对训练数据加权的方法
  15. Ubuntu高分屏下Matlab工具栏字体过小
  16. 从零开始学 Python 之环境搭建
  17. 百奥赛图与TRACON共同宣布YH001(CTLA-4单抗)联合恩沃利单抗(PD-L1)一线治疗软组织肉瘤的临床试验申请获得FDA批准
  18. 保护元件、设备人身安全防护(四川防电盾)
  19. Linux-Linux内核-进程调度
  20. 当这个类被修饰public的话,为什么源文件名必须要与类名相同

热门文章

  1. php Wrapper LFI,PHP安全之LFI漏洞GetShell方法大阅兵
  2. 用css3的transition实现过渡动画
  3. Hexo+Butterfly 快速搭建个人博客【附源码】
  4. Firefox os 游戏开发之2048游戏源码
  5. php swoole入门到实站视频资源
  6. C语言的链表和数组-诺禾
  7. 传统数据仓库 DW/EDW/BI/ODS/DM/ETL
  8. VLAN应用篇系列:(10)H3C交换机 PVLAN功能(V7为PVLAN,V5为isolate-user-vlan)
  9. Linux rm命令详解,Linux删除文件目录
  10. 如何用AR引擎技术, 5步优雅实现物体识别和跟踪