8.4 SQL 执行器
SQL 执行器是 DataQL 引擎的片段执行器扩展。dataql-sqlproc 实现 FragmentProcess,通过 JDBC 执行脚本中的 SQL 片段,完成参数绑定和语句执行。
独立使用时,引入该模块,并通过 HostConfiguration 注册 ConnectionProvider 提供数据库连接。
引入 SQL 执行器
在引擎依赖之外添加以下模块,并引入所用数据库的 JDBC 驱动和连接池。
- Maven
- Gradle
<dependency>
<groupId>net.hasor</groupId>
<artifactId>dataql-sqlproc</artifactId>
<version>5.0.0</version>
</dependency>
implementation 'net.hasor:dataql-sqlproc:5.0.0'
注册连接并执行 SQL
下面的 source 是应用已创建的 DataSource。在创建查询前注册连接提供者,再通过 QueryManager → QueryBuilder → Query 执行脚本。
import net.hasor.dataql.host.HostConfiguration;
import net.hasor.dataql.host.Query;
import net.hasor.dataql.host.QueryManager;
import net.hasor.dataql.sqlproc.execute.support.ConnectionProvider;
ConnectionProvider provider = (name, hints) -> source.getConnection();
HostConfiguration host = new HostConfiguration();
host.addAttachment(ConnectionProvider.class, provider);
QueryManager manager = new QueryManager(host);
Query query = manager.newBuilder().createQuery("""
var find = @@selectSql(value)<% SELECT #{value} AS result_value %>;
return find(42);
""");
Object value = query.execute().getData().unwrap(); // 42
selectSql 等片段由模块自动注册,无需手动添加。#{value} 绑定调用 find 时传入的参数,查询结果为 42。
未指定数据源时,传给 ConnectionProvider 的名称为空字符串。普通 SQL 执行结束后关闭本次连接;使用连接池时通常表示归还连接。连接池由应用创建和关闭。
多数据源
在创建 QueryManager 前,将单数据源的连接提供者替换为按名称查找。下面的 primarySource 为默认数据源,reportingSource 通过名称 reporting 访问。
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import net.hasor.dataql.sqlproc.execute.support.ConnectionProvider;
Map<String, DataSource> sources = Map.of("", primarySource, "reporting", reportingSource);
ConnectionProvider provider = (name, hints) -> {
DataSource selected = sources.get(name);
if (selected == null) {
throw new SQLException("Unknown data source: " + name);
}
return selected.getConnection();
};
host.addAttachment(ConnectionProvider.class, provider);
hint FRAGMENT_SQL_DATA_SOURCE = 'reporting';
var find = @@selectSql(value)<% SELECT #{value} AS result_value %>;
return find(42);
FRAGMENT_SQL_DATA_SOURCE 将名称传给 ConnectionProvider。不同名称可以对应不同数据库和驱动,未知名称直接报错。
类型处理器
SQL 执行器通过 TypeHandler 完成 Java 值与 JDBC 参数、结果列之间的转换,内置字符串、数值、日期时间和二进制等处理器。应用可按参数指定处理器,或注册默认处理器统一转换;实现、注册和使用示例见 SQL 类型处理器,脚本参数选项见类型处理。
接入事务
多条 SQL 需要共同提交或回滚时,在创建查询前包装已配置的连接提供者,仍按 ConnectionProvider 类型注册。
import net.hasor.dataql.sqlproc.execute.transaction.TransactionProvider;
TransactionProvider transactions = new TransactionProvider(provider);
host.addAttachment(ConnectionProvider.class, transactions);
脚本通过 TransactionUdfSource 执行事务回调,普通 SQL 和事务函数共用该连接提供者。包装对象由应用管理生命周期,传播行为和脚本用法见事务。
SQL 语法、参数绑定和结果处理见 SQL 执行。执行扩展见 SQL 拦截器、SQL 片段、SQL 规则和 SQL 方言。