1. 程式人生 > >Esper學習筆記四:EPL語法(2)

Esper學習筆記四:EPL語法(2)

1.select

查詢所有屬性或特定屬性

EPL的select和SQL的select很相近,SQL用*表示查詢表的所有欄位,而EPL用*表示查詢事件流的所有屬性值。SQL查詢某個欄位名,直接在select後跟欄位名就ok,EPL也是將要查詢的屬性名放在select之後。若查多個屬性值,則用逗號分割。和SQL一樣,EPL查詢屬性也可以設定別名。

//EPL:查詢所有屬性
select * from myEvent
//在監聽器中獲取完整物件
MyEvent me = (MyEvent)eb.getUnderlying();

// EPL:查詢MyEvent的name和age,age別名為a
select name,age as a from myEvent
//在監聽器中獲取查詢屬性
String name = (String)eb.get("name");
Integer a = (Integer)eb.get("a");

表示式

除了查詢完整物件和屬性外,EPL還支援屬性值的計算,以計算的值作為結果返回。

// 計算長方形的面積(長乘以寬)
select length * width as area from Rectangle

除了簡單的加減乘除,還可以利用事件流物件的某個方法

// 計算長方形的面積(長乘以寬)
select r.getArea(r.length,r.width) as area from Rectangle as r

select r.getArea() as area from Rectangle as r

定義計算面積方法


// Rectangle類
public class Rectangle
{
    private int length;
    private int width;
 
    /** 省略getter/setter方法 **/
    // 外部傳入引數計算面積
    public int getArea(int l, int w){
        return l*w;
    }
 
    // 計算該物件的面積
    public int getArea(){
        return length * width;
    }
}

如上所示,一個方法需要傳參,另一個方法不需要,但是他會利用當前事件的length和width來計算面積。而且要注意的是事件流需要設定別名才能使用其方法。

如果Rectangle類裡沒有計算面積的方法,但是提供了一個專門計算面積的靜態方法的工具類,表示式也可以直接引用。不過要事先載入這個包含方法的類。

// 該類用於計算面積
public class ComputeArea{
	
	public static int getArea(int length, int width){
		return length*width;
	}
}
 
// 載入
epService.getEPAdministrator().getConfiguration().addImport(ComputeArea.class);

在EPL中呼叫計算方法

// 呼叫ComputeArea的getArea方法計算面積
select ComputeArea.getArea(length,width) from Rectangle

多事件流查詢

和SQL中的多表查詢類似,EPL也可以同時對多個事件流進行查詢,即join,但是必須對每個事件流設定別名。

// 在10秒鐘內當老師的id和學生的id相同時,查詢學生的姓名和老師的姓名
select s.name, t.name from Student.win:time(10 sec) as s, Teacher.win:time(10 sec) as t where s.id=t.id

如果想查詢Student或者Teacher,則EPL改寫如下

select s.* as st, t.* as tr from Student.win:time(10 sec) as s, Teacher.win:time(10 sec) as t where s.id=t.id

insert和remove事件流

Esper對於事件流分輸入和移出兩種,分別對應監聽器的兩個引數newEvents和oldEvents。

Distinct

去重。

2.From

語法

From的語法不難,主要內容是針對事件流的處理。包括事件流過濾,事件流的維持等等。

事件流過濾

事件流過濾通常情況都是對其中某個或多個屬性加以限制來達到過濾的目的。

// 只有age大於10的User物件才可查詢到name值
select name from User(age>10) as user
// 當name=''時,可獲得其age值
select age from User(name='')

過濾表示式寫法多種多樣,可以用逗號“,”,又或者使用and,or,between等邏輯語言。

// 查詢年齡大於15小於18的學生的姓名
select name from Student(age between 15 and 18)
// 等同於
select name from Student(age >= 15 and age <= 18)
// 等同於
select name from Student(age >= 15, age <= 18)

過濾條件有多種多樣,主要有<, >, <=, >=, =, !=, between...and..., in, not in, [ ], ( )。

between...and...

和SQL的between……and……意思一樣,是一個閉區間。比如說between 10 and 15,中文語義為10到15之間幷包含10和15。

in

配合( )和[ ]進行使用,表示值在某個範圍內。

not in

表示不在某個範圍內

( ):表示一個開區間,語法為(low:high)。如(10:15),表示10到15之間,並且不包含10和15。

[ ]:表示一個閉區間,語法為[low:high]。如[10:15],表示10到15之間,並且包含10和15

( )和[ ]可以混合用。比如[10:15)或者(10:15]

例如:

select name from User(age in [10:15))
select age from User(name in ('張三', '李四'))

靜態方法過濾

除了上面說的這些符號以外,類似於select子句中使用的靜態方法,過濾表示式中也可以使用,但是返回值必須為布林值,不然會報錯。

/ 判斷總數是否等於0
public class IsZero
{
	public static boolean isZero(int sum)
	{
		return sum==0;
	}
}
 
// 載入
epService.getEPAdministrator().getConfiguration().addImport(IsZero.class);
 
// 查詢沒有錢的使用者的name值(User包含name和money屬性)
select name from User(IsZero.isZero(money))

1. 要過濾的屬性只能是數字和字串。
2. 過濾表示式中不能使用聚合函式。

 

轉載:https://blog.csdn.net/luonanqin/article/details/11877127