官方地址:http://www.espertech.com
Esper 事件引擎栏目:http://blog.csdn.net/xiaohulunb/article/category/2436609
EPL 语法代码见-GitHub代码地址:点击打开链接
涉及 Javabean,Listener,main 以 GitHub 包下为最新更,注释解释排版有问题可参考源码
package com.framework_technology.esper.epl; import com.framework_technology.esper.javabean.Apple; import com.framework_technology.esper.javabean.Banana; import com.java.annotation.document.Undigested; /** * API - 5.15. Creating and Using Named Windows * * 创建 NamedWindow * 插入数据 * 查询数据、按条件触发查询数据 * 修改数据 * 删除数据 * 合并事件NamedWindow * 对NamedWindow建立索引 * * @author wei.Li by 14-8-21. */ public class EPL_8_NamedWindow { /** * 创建 window - ①在现有的数据类型上创建列 * <p> * 语法: * [context context_name] * create window window_name.view_specifications * [as] [select list_of_properties from] event_type_or_windowname * [insert [where filter_expression]] * <p> * 1)context是关键字,后面跟着之前定义的context的名称。 * 关于context的内容,{@link EPL_2_Context_1,EPL_2_Context_2,EPL_2_Context_3} * 2)create window后跟着要创建的named window的名字,且具有唯一性。名字后面紧跟着的“.”是用来连接事件过期策略的,即view。 * 常用的view有win:length,win:length_batch,win:time,win:time_batch,std:unique,std:groupwin及自定义view等等,并且特定的view可以连用。 * PS:view的相关内容{@link com.framework_technology.esper.views.View} * 3)select子句表示将某个事件定义中的全部或者某些属性作为named window所维护的事件属性。 * 如果将某个事件的所有属性都加入到named window中,则可以通过select子句前的as连接事件名称,并且省略select子句。 * * @return epl */ protected static String createWindowExistingType() { String epl1 = "create window AppleWindow.win:keepall() as " + Apple.CLASSNAME; String epl2 = "create window AppleWindow.win:time(30 sec) as " + " select id as appleId, price as applePrice from OrderEvent"; return epl1; } /** * 创建 window - ②自定义列的数据类型 * <p> * 语法: * [context context_name] * create window window_name.view_specifications [as] (column_name column_type * [,column_name column_type [,...]) * * @return epl */ protected static String createWindowDefiningColumnsNamesAndTypes() { String epl1 = "create window SecurityEvent.win:time(30 sec) " + "(ipAddress string, userId String, numAttempts int, properties String[])"; @Undigested(Description = "what is schema ?") String epl2 = "create schema SecurityData (name String, roles String[])"; String epl3 = "create window SecurityEvent.win:time(30 sec) " + " (ipAddress string, userId String, secData SecurityData, historySecData SecurityData[])"; return epl1; } /** * 创建 window - ③将存在的 window 数据插入到新创建的 window 中 * <p> * 语法:[context context_name] create window window_name.view_specifications as windowname insert [where filter_expression] * <p> * windowname后面紧跟insert,表示将该window中的事件插入到新建的named window中。where filter_expression表示过滤插入的事件。 * * @return epl */ protected static String populatingExistingNamedWindow() { String epl1 = "create window BananaEventWindow.win:time(10) as AppleEventWindow insert where price > 100"; return epl1; } /** * 销毁 window */ protected static void dropNamedWindow() { //EPStatement epStatement = epAdministrator.createEPL("epl . . ."); //epStatement.destroy(); } /** * 插入数据到 window * <p> * 语法:insert into window_name [(property_names)] [values (value_expressions) 或者查询方式 select value_expressions] * <p> * 查询 window 的数据,与普通查询相同 * * @return epl[] */ protected static String[] insertIntoDate() { String query_1 = "insert into OrdersWindow(orderId, symbol, price) values ('001', 'GE', 100)"; //epService.getEPRuntime().executeQuery(query); String query_2 = "insert into OrdersWindow(orderId, symbol, price) select '001', 'GE', 100"; //epService.getEPRuntime().executeQuery(query); //新建 window - 插入数据 - 查询数据 String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME; String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME; String epl3 = "select * from AppleWindow(price>1) ";//查询方式与查询 javabean 方式相同 return new String[]{epl1, epl2, epl3}; } /** * 按照一定条件触发查询 window 的数据 * <p> * 语法: * on event_type[(filter_criteria)] [as stream_name] * [insert into insert_into_def] * select select_list * from window_name [as stream_name] * [where criteria_expression] * [group by grouping_expression_list] * [having grouping_search_conditions] * [order by order_by_expression_list] * * @return EPL[] */ protected static String[] triggeredOnSelect() { //新建 window - 插入数据 String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME; String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME; //触发条件查询 String epl3 = "on " + Banana.CLASSNAME + " as b select win.* from AppleWindow as win "; // "where b.id ='1' group by win.price having win.price >0 order by win.price"; //将查询结果插入AppleWindow 中 String epl4 = "on " + Banana.CLASSNAME + " as b insert into AppleWindow select * from AppleWindow as win "; // "where a.id ='1' group by win.price having win.price >1 order by win.price"; return new String[]{epl1, epl2, epl3}; } /** * 按照条件触发查询并删除 window 的数据 * on trigger * select [and] delete select_list... * ... (please see on-select for insert into, from, group by, having, order by)... * * @return epl[] */ protected static String[] triggeredOnSelectDelete() { //新建 window - 插入数据 String epl1 = "create window AppleWindow.win:keepall() as select id ,price from " + Apple.CLASSNAME; String epl2 = "insert into AppleWindow select id,price from " + Apple.CLASSNAME; //触发条件查询 String epl3 = "on " + Apple.CLASSNAME + " as a select and delete window(win.*) from AppleWindow as win "; //"where a.id ='1' group by win.price having win.price >1 order by win.price"; return new String[]{epl1, epl2, epl3}; } /** * 更新 Update window 数据 * <p> * on event_type[(filter_criteria)] [as stream_name] * update window_name [as stream_name] * set mutation_expression [, mutation_expression [,...]] * [where criteria_expression] * * @return epl[] */ protected static String[] updateNamedWindow() { //simple example String epl1 = "on UpdateOrderEvent update AllOrdersNamedWindow set price = 0"; String epl2 = "on ZeroVolumeEvent update AllOrdersNamedWindow set price = 0 where volume <= 0"; //对于OrderUpdateEvent或者FlushOrderEvent事件进入后触发修改 win set 的条件用 if else 匹配 String epl3 = "on pattern [every ord=OrderUpdateEvent(volume>0) or every flush=FlushOrderEvent] " + "update AllOrdersNamedWindow as win" + "set price = case when ord.price is null then flush.price else ord.price end" + "where ord.id = win.id or flush.id = win.id"; String epl4 = "on UpdateEvent as upd" + "update MyWindow as win" + "set field_a = 1," + "field_b = win.field_a," + // 把 a修改后的值 1 赋给 b "field_c = initial.field_a ";// 把 a 更新前的值赋值给 c(关键字 initial) /** * 针对 epl4 : * update更新属性前会复制一份同样的事件暂存,比如initial这种操作就需要更新前的值,所以就需要我们实现序列化接口。 * 如果不想通过代码完成这个序列化要求,也可以通过配置完成。 * 另外还有以下几点需要注意: a)需要更新的属性一定要是可写的 b)XML格式的事件不能通过此语句更新 c)嵌套属性不支持更新 */ //Query 方式更新 String query = "update AllOrdersNamedWindow set volume = 0 where volumne = 0"; //epService.getEPRuntime().executeQuery(query); return new String[]{epl1, epl2}; } /** * 删除 delete window 的数据 * <p> * 语法: * on event_type[(filter_criteria)] [as stream_name] (Pattern 匹配->on pattern [pattern_expression] [as stream_name]) * delete from window_name [as stream_name] * [where criteria_expression] * * @return epl[] */ protected static String[] deleteNamedWindow() { //事件触发 String epl1 = "on ZeroVolumeEvent delete from AllOrdersNamedWindow where volume <= 0"; String epl2 = "on NewOrderEvent(volume>0) as myNewOrders" + "delete from AllOrdersNamedWindow as myNamedWindow " + "where myNamedWindow.symbol = myNewOrders.symbol"; //Pattern 模式匹配 String epl3 = "on pattern [every timer:interval(10 sec)] delete from MyNamedWindow"; String epl4 = "on pattern [every ord=OrderEvent(volume>0) or every flush=FlushOrderEvent] " + "delete from OrderWindow as win" + "where ord.id = win.id or flush.id = win.id"; //Query 方式删除 String query = "delete from AllOrdersNamedWindow where volume <= 0"; //epService.getEPRuntime().executeQuery(query); return new String[]{epl2, epl2}; } /** * 合并事件 * <p> * * @return epl[] */ protected static String[] MergeWindow() { /*语法: on event_type[(filter_criteria)] [as stream_name] merge [into] window_name [as stream_name] [where criteria_expression] when [not] matched [and search_condition] then [ insert [into streamname] [ (property_name [, property_name] [,...]) ] select select_expression [, select_expression[,...]] [where filter_expression] | update set mutation_expression [, mutation_expression [,...]] [where filter_expression] | delete [where filter_expression] ] [then [insert|update|delete]] [,then ...] [when ... then ... [...]] */ /* a.第一行和前面的用法都一样。 b.第二行的where语句将事件分为了matched(满足where条件)和not matched(不满足where条件)两类 c.第三行的when配合matched或者not matched表示“window中满足where条件的事件,执行下面的操作/window中不满足where条件的事件,执行下面的操作”。 search_condition为可选字段,表示再次过滤matched或not matched中的事件,只有没被过滤掉的事件才可以被then后面的语句操作。 d.第四行的insert语句和之前说的insert into不太一样。 虽然都表示插入事件,但是由于into streamname是可选,所以在只有insert关键字的情况下,会将触发的事件插入到当前的named window中。 如果要指明插入到别的named window中就要在insert之后带上into及window的名字。 再之后的圆括号中的内容表示要插入的事件的属性,一般情况是在将事件插入到别的window中时,用它来重命名第五行中列出的属性。 e.第五行实际是配合第四行一起使用的。select子句不可少,不然引擎就不知道要往window中插入什么内容了。 select的内容可以是*,也可以是属性列表。where语句再一次限制可插入的触发事件。注意select后面没有from,因为事件来源就是当时的触发事件。 f.第七行用来更新符合条件的事件,可更新单个或多个属性,where条件判断是否可进行更新操作。 g.第九行用来删除符合条件的事件,只包含关键字delete以及可选的where语句。 h.最后两行表示on merge中可以有多个when,每个when可以有多个then及insert或updata或delete语句,这样就能组成一个非常复杂的merge操作了。 */ //在下面的例子中每一个匹配子句包含两个动作,一个动作中插入一个日志事件和第二动作插入、删除或更新 String epl1 = "on OrderEvent oe" + " merge OrderWindow pw" + " where pw.orderId = oe.orderId" + " when not matched " + " then insert into LogEvent select 'this is an insert example' as name" + " then insert select *" + " when matched and oe.deletedFlag=true" + " then insert into LogEvent select 'this is a delete example' as name" + " then delete" + " when matched" + " then insert into LogEvent select 'this is a update example' as name" + " then update set pw.quantity = oe.quantity, pw.price = oe.price"; //根据条件判断,进行2此修改 String epl2 = "on OrderEvent oe" + " merge OrderWindow pw" + " where pw.orderId = oe.orderId" + " when matched" + " then update set clearorder(pw) where oe.price < 0" + " then update set pw.quantity = oe.quantity, pw.price = oe.price where oe.price >= 0"; return new String[]{epl1, epl2}; } /** * 对named window中存放的事件的属性建立索引 * <p> * 语法: * create [unique] index index_name on named_window_name (property [hash| btree] [, property] [hash|btree] [,...] ) * <p> * unique代表建立唯一索引,如果插入了重复的行,则会抛出异常并阻止重复行插入。 * 如果不使用此关键字,则表示可以插入重复行。 * index_name为索引的名称,named_window_name是要建立索引的named window。 * 后面的括号中包含named window中的属性以及索引类型。 * 索引类型分两种,hash索引不会排序,如果有=操作,建议使用此类型索引。 * btree索引基于排序二叉树,适合<, >, >=, <=, between, in等操作。 * 如果不显式声明hash或者btree,则默认为hash索引。 * * @return epl[] */ protected static String[] IndexingNamedWindows() { String epl1 = "create unique index UserProfileIndex on UserProfileWindow(userId, profileId) "; String epl2 = "create index idx1 on TickEventWindow(symbol hash, buyPrice btree) "; return new String[]{epl1, epl2}; } }