6.1 SQL 执行
运行脚本前,先完成 SQL 执行器的接入配置。
SQL 片段先声明参数和 SQL,再通过函数调用执行。注册名决定操作类型和正文格式。
| 操作 | 文本 SQL | XML 动态 SQL | 返回值 |
|---|---|---|---|
| 查询 | selectSql | selectXml | 查询结果或分页对象 |
| 插入 | insertSql | insertXml | 影响行数 |
| 更新 | updateSql | updateXml | 影响行数 |
| 删除 | deleteSql | deleteXml | 影响行数 |
| 存储过程 | callSql | callXml | 结果集、更新计数或指定输出 |
| 通用执行 | executeSql | executeXml | 按语句产生的结果返回 |
已知操作类型时使用对应注册名;executeSql 按 SQL 开头识别操作,复杂语句宜显式选用 selectSql、updateSql 等。
示例数据
本章查询示例使用以下 H2 表和数据;其他数据库按其建表语法创建相同字段即可。
CREATE TABLE people (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(100),
age INT,
enabled INT DEFAULT 1
);
INSERT INTO people(name, age) VALUES ('Alice', 25), ('Bob', 30);
可运行脚本和 H2 验证代码位于仓库的 dataql/dataql-sqlproc/src/test/resources/sql-manual 和对应的 documentation 测试包。
查询
hint FRAGMENT_SQL_OPEN_PACKAGE = 'off';
hint FRAGMENT_SQL_COLUMN_CASE = 'lower';
var find = @@selectSql(minAge)<%
SELECT id, name, age FROM people WHERE age >= #{minAge} ORDER BY id
%>;
return find(25);
返回 Alice、Bob 两行。off 保持列表结构,lower 将列名转为小写,详见结果与主键。
增删改
var add = @@insertSql(name, age)<% INSERT INTO people(name, age) VALUES (#{name}, #{age}) %>;
var change = @@updateSql(name, age)<% UPDATE people SET age = #{age} WHERE name = #{name} %>;
var find = @@selectSql(name)<% SELECT age FROM people WHERE name = #{name} %>;
var remove = @@deleteSql(name)<% DELETE FROM people WHERE name = #{name} %>;
var inserted = add('Carol', 20);
var updated = change('Carol', 21);
var age = find('Carol');
var deleted = remove('Carol');
return {'inserted': inserted, 'updated': updated, 'age': age, 'deleted': deleted};
插入、更新、删除分别返回影响行数。以上调用逐条执行,需要原子性时放入事务。
批量调用
片段名后加 [],调用参数使用列表:
var add = @@insertSql[](person)<%
INSERT INTO people(name, age) VALUES (#{person.name}, #{person.age})
%>;
return add([{'name':'Carol','age':20}, {'name':'Dave','age':22}]);
返回 [1, 1]。多个形参均需传入等长列表,按相同下标配对执行。当前实现逐项调用 JDBC,并非 JDBC executeBatch;需要全部成功或全部回滚时,用事务包住整次调用。
执行选项
hint timeout = 5;
hint fetchSize = 100;
var find = @@selectSql()<% SELECT id, name FROM people %>;
return find();
默认使用 PreparedStatement。超时单位为秒,fetchSize 是驱动的取数提示;全部配置见 SQL Hint。执行异常向 DataQL 调用方传播。
参数作用域
DataQL 中的 ${id} 先读取脚本参数,再作为片段实参传入;SQL 正文中的 #{id} 绑定片段形参。SQL 内的 ${id} 表示文本替换。完整语法见参数绑定。