跳到主要内容

5.5 数据源接入

引入 dataql-sqlproc,通过 ConnectionProvider 提供 JDBC 连接,并注册到 DatawayConfig。以下三种配置按需选择。

不接入事务​

ConnectionProvider.findConnection(sourceName, hints) 接收数据源名称和执行选项,返回 JDBC 连接。以下示例使用已有的 primarySource、ds1、ds2,未指定名称时选择主数据源:

直接提供数据库连接
import java.util.Map;
import javax.sql.DataSource;
import net.hasor.dataql.sqlproc.execute.support.ConnectionProvider;
import net.hasor.dataway.service.DatawayConfig;

Map<String, DataSource> sources = Map.of("ds1", ds1, "ds2", ds2);
ConnectionProvider connections = (name, hints) -> {
DataSource source = name == null || name.isBlank()
? primarySource : sources.get(name);
return source == null ? null : source.getConnection();
};

DatawayConfig config = new DatawayConfig()
.attachment(ConnectionProvider.class, connections);

SQL 执行后关闭连接,提交行为遵循连接设置,通常为自动提交。后续失败不会撤销已提交的修改;调用事务函数 tran.* 需要接入下列事务提供者。

接入事务​

事务提供者实现 TransactionalProvider,统一提供连接和事务控制。

DataQL 本地事务​

用 TransactionProvider 包装上面的连接提供者:

接入 DataQL 本地事务
import net.hasor.dataql.sqlproc.execute.transaction.TransactionProvider;

TransactionProvider transactions = new TransactionProvider(connections);
DatawayConfig config = new DatawayConfig()
.attachment(ConnectionProvider.class, transactions);

tran.required(...) 等函数控制提交与回滚,同一线程、同一数据源名称共享事务连接。该事务独立于宿主框架;事务外的 SQL 遵循连接的提交设置。

宿主事务​

框架提供者将 SQL、tran.* 和应用数据库操作接入同一套事务管理。以 Spring 为例:

接入 Spring 事务
import net.hasor.dataway.spring.SpringTransactionProvider;

ConnectionProvider transactions = new SpringTransactionProvider(applicationContext);
DatawayConfig config = new DatawayConfig()
.attachment(ConnectionProvider.class, transactions);

同一线程、同一数据源的 SQL 加入已有事务,tran.required(...) 加入或创建宿主事务。应用也需通过框架获取事务连接。具体配置见:

事务函数用法见事务函数库。上述事务按数据源管理,跨库原子提交需另行接入分布式事务。

选择与组合数据源​

FRAGMENT_SQL_DATA_SOURCE 指定传给连接提供者的数据源名称。下面从 ds1 查询人员、ds2 查询订单,合并为一个结果:

组合人员与订单
{
hint FRAGMENT_SQL_DATA_SOURCE = "ds1"
var findPerson = @@selectSql(id)<%
SELECT id AS "id", name AS "name"
FROM example_people WHERE id = #{id}
%>;
var person = findPerson(${id});
}
{
hint FRAGMENT_SQL_DATA_SOURCE = "ds2"
hint FRAGMENT_SQL_OPEN_PACKAGE = "off"
var findOrders = @@selectSql(id)<%
SELECT id AS "id", product AS "product", amount AS "amount"
FROM example_orders WHERE person_id = #{id} ORDER BY id
%>;
var orders = findOrders(${id});
}
return {"person": person, "orders": orders};

${id} 接收请求参数,#{id} 绑定 SQL 值,FRAGMENT_SQL_OPEN_PACKAGE = "off" 保持订单结果为列表。完整配置见样例工程。