函数/函数包
开发 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));
});