8.5 JSR-223
dataql-engine 提供 JDK javax.script 接口,可通过 ScriptEngineManager 发现引擎,支持脚本执行和 Compilable 预编译。
执行脚本
Jsr223Example.java
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import net.hasor.dataql.kernel.QueryResult;
public class Jsr223Example {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("dataql");
if (engine == null) {
throw new IllegalStateException("dataql-engine is missing from the runtime classpath");
}
engine.put("name", "DataQL");
QueryResult result = (QueryResult) engine.eval("return ${name};");
System.out.println(result.getData().unwrap());
}
}
输出为 DataQL。eval 返回 QueryResult,通过 getData().unwrap() 读取实际结果。也可按扩展名 dql 或媒体类型 application/x-dataql 查找引擎。
预编译与按次传参
以下代码接续上例的 engine,编译一次,使用独立上下文执行两次:
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import net.hasor.dataql.host.jsr223.QueryScriptContext;
import net.hasor.dataql.kernel.QueryResult;
CompiledScript compiled = ((Compilable) engine).compile("return ${name};");
QueryScriptContext defaults = (QueryScriptContext) engine.getContext();
for (String name : new String[] {"Alice", "Bob"}) {
QueryScriptContext context = new QueryScriptContext(defaults.getHostContext());
context.setAttribute("name", name, ScriptContext.ENGINE_SCOPE);
QueryResult result = (QueryResult) compiled.eval(context);
System.out.println(result.getData().unwrap());
}
输出为 Alice、Bob。上下文必须使用 QueryScriptContext,并与引擎共享同一个 HostContext。当前实现不接受普通 SimpleScriptContext,eval(script, bindings) 和 compiled.eval(bindings) 也不支持;按次传参使用上述方式。
参数与配置
engine.put(...)写入ENGINE_SCOPE。取参数时先合并GLOBAL_SCOPE,再由ENGINE_SCOPE覆盖同名值;$、@、#读取相同的合并结果。GLOBAL_SCOPE的键还会声明为共享变量,可在脚本中直接使用变量名;这些键应在编译前设置。新建上下文需要自行设置所需的全局 Bindings。- 通过
((QueryScriptContext) engine.getContext()).getConfiguration()获取HostConfiguration,按核心接口注册扩展。 - 引擎实现
Compilable,未实现Invocable。运行阶段的QueryRuntimeException包装为ScriptException,语法或编译错误可能直接抛出对应异常。