Skip to main content

函数/函数包

开发 UDF:

一个 UDF 必须是实现 net.hasor.dataql.Udf 接口,例如下面这个 UDF。

public class UserByIdUdf implements Udf {
private UserManager userManager;

public Object call(Hints readOnly, Object[] params) {
return userManager.findById(params[0]);
}
}

注册 UDF 的方式和添加全局变量相同,这里不再复述。最后执行查询并提取姓名和性别:

DataQL dataQL = appContext.getInstance(DataQL.class);//得到 DataQL接口
Query dataQuery = dataQL.createQuery("return findUserById(1) => { 'name','sex' }"); // 创建查询
QueryResult queryResult = dataQuery.execute();//执行查询
DataModel dataModel = queryResult.getData(); //获得查询结果

参数中的 UDF

DataQL 允许在执行查询时通过参数形式提供 UDF ,这种方式传入的 UDF 在调用时也需要使用 ${...} 来获取,例如:

HashMap<String, Object> tempData = new HashMap<String, Object>() {{
put("findUserById", new UserByIdUdf());
}};

AppContext appContext = Hasor.create().build();
DataQL dataQL = appContext.getInstance(DataQL.class);//得到 DataQL接口
Query dataQuery = dataQL.createQuery("return ${findUserById}(1) => { 'name','sex' }"); // 创建查询
QueryResult queryResult = dataQuery.execute(tempData);
DataModel dataModel = queryResult.getData();

函数包(UdfSource)

UdfSource 是一个函数包接口,接口中只有一个 getUdfResource 方法,用于返回函数包中的所有 UDF(Map形式返回)但是一般情况下更推荐使用 UdfSourceAssembly 接口。

使用函数包的好处是可以像平常开发一样编写 Udf,无需考虑 Udf 接口的细节。装配器会自动帮助进行参数和结果的转换。例如:

public class DateTimeUdfSource implements UdfSourceAssembly {
/** 返回当前时间戳 long 格式 */
public long now() { ... }

/** 返回当前系统时区的:年 */
public int year(long time) { ... }

/** 返回当前系统时区的:月 */
public int month(long time) { ... }

/** 返回当前系统时区的:日 */
public int day(long time) { ... }
...
}

最后在查询中通过 <函数包名>.<函数> 的形式调用函数包。

import导入(函数/函数包)

如果 Classpath 中已经存在某个 UDF 类,还可以通过 import 语句导入使用。

import 'net.xxxx.foo.udfs.UserByIdUdf' as findUserById;
return findUserById(1) => { 'name','sex' };

函数包的导入语句相同,只是在调用函数包中函数的时需要指明函数包,例如:

import 'net.xxxx.foo.udfs.DateTimeUdfSource' as timeUtil;
return timeUtil.now();

使用注解批量注册

通过 @DimUdf 注解可以快速的声明函数:

@DimUdf("findUserById")
public class UserByIdUdf implements Udf {
private UserManager userManager;

public Object call(Hints readOnly, Object[] params) {
return userManager.findById(params[0]);
}
}

通过 @DimUdfSource 注解可以快速的声明函数包:

@DimUdfSource("time_util")
public class DateTimeUdfSource implements UdfSourceAssembly {
...
}

然后在初始化时扫描加载它们:

AppContext appContext = Hasor.create().build(apiBinder -> {
QueryApiBinder queryBinder = apiBinder.tryCast(QueryApiBinder.class);
queryBinder.loadUdf(queryBinder.findClass(DimUdf.class));
queryBinder.loadUdfSource(queryBinder.findClass(DimUdfSource.class));
});