函数/函数包

开发Udf

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

  1. public class UserByIdUdf implements Udf {
  2. private UserManager userManager;
  3. @Override
  4. public Object call(Hints readOnly, Object[] params) {
  5. return userManager.findById(params[0]);
  6. }
  7. }

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

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

参数中的Udf

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

  1. HashMap<String, Object> tempData = new HashMap<String, Object>() {{
  2. put("findUserById", new UserByIdUdf());
  3. }};
  4. AppContext appContext = Hasor.create().build();
  5. DataQL dataQL = appContext.getInstance(DataQL.class);//得到 DataQL接口
  6. Query dataQuery = dataQL.createQuery("return ${findUserById}(1) => { 'name','sex' }"); // 创建查询
  7. QueryResult queryResult = dataQuery.execute(tempData);
  8. DataModel dataModel = queryResult.getData();

函数包(UdfSource)

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

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

  1. public class DateTimeUdfSource implements UdfSourceAssembly {
  2. /** 返回当前时间戳 long 格式 */
  3. public long now() { ... }
  4. /** 返回当前系统时区的:年 */
  5. public int year(long time) { ... }
  6. /** 返回当前系统时区的:月 */
  7. public int month(long time) { ... }
  8. /** 返回当前系统时区的:日 */
  9. public int day(long time) { ... }
  10. ...
  11. }

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

import导入(函数/函数包)

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

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

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

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

使用注解批量注册

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

  1. @DimUdf("findUserById")public class UserByIdUdf implements Udf { private UserManager userManager; @Override public Object call(Hints readOnly, Object[] params) { return userManager.findById(params[0]); }}

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

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

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

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