存储过程调用
dbVisitor 支持存储过程调用以及输入、输出参数处理,常见场景包括:
执行存储过程
各节是独立示例;同名过程不能重 复创建。MySQL 客户端执行 CREATE PROCEDURE 时需配置语句分隔符,或通过 JDBC 将整个定义一次发送。
有如下 MySQL 存储过程,接受一个参数并产生一个结果集。
1. MySQL 存储过程
create procedure proc_select_table(in userName varchar(200))
begin
select * from test_user where name = userName;
end;
2. 编辑查询语句
{call proc_select_table(?)} @{resultSet,name=res,javaType=net.demo.UserDTO}
- 调用 proc_select_table 存储过程,并且通过位置参数形式传递入参。
- 通过 RESULT 规则 声明在调用存储过程后,将产生的结果集映射为 UserDTO 对象。
3. 执行存储过程
JdbcTemplate jdbc = ...
Map<String, Object> res = jdbc.call("{call proc_select_table(?)} @{resultSet,name=res,javaType=net.demo.UserDTO}",
"Kevin");
List<UserDTO> result = (List<UserDTO>)res.get("res");
- 配置了规则后调用存储过程的最终 SQL 语句。
- 传递入参
- 获取 RESULT 规则 处理后的结果集,名称为 res。
信息
如果存储过程有意或者无意产生多个结果集,可以通过使用多个 RESULT 规则 来分别处理它们。
使用名称参数
执行存储过程
JdbcTemplate jdbc = ...
Map<String, Object> res = jdbc.call("{call proc_select_table(:userName)} @{resultSet,name=res,javaType=net.demo.UserDTO}",
CollectionUtils.asMap("userName", "Kevin"));
List<UserDTO> result = (List<UserDTO>)res.get("res");
区别为将 ? 方式传递参数改为使用 :userName 方式传参。
信息
- dbVisitor 支持多种参数传递方式,想要了解更多参数传递内容请到 参数传递 页面查看。
获取 OUT 参数值
1. 有如下 MySQL 存储过程
create procedure proc_select_table(in userName varchar(200), out outName varchar(200)) -- 传出参数
begin
select * from test_user where name = userName;
set outName = concat(userName,'-str');
end;
- 接收的传入参数。
- 产生的传出参数。
- 存储过程执行生成的结果集。
2. 编辑查询语句
{
call proc_select_table(#{userName,jdbcType=varchar},
#{outName, mode=out,jdbcType=varchar})
} @{resultSet,name=res,javaType=net.demo.UserDTO}
3. 执行存储过程
JdbcTemplate jdbc = ...
Map<String, Object> args = CollectionUtils.asMap("userName", "Kevin");
Map<String, Object> res = jdbc.call(
"{call proc_select_table(#{userName,jdbcType=varchar}, " +
" #{outName, mode=out,jdbcType=varchar})" +
"} @{resultSet,name=res,javaType=net.demo.UserDTO}",
args
);
String outName = (String)res.get("outName");
List<UserDTO> result = (List<UserDTO>)res.get("res");
OUT 参数中使用游标
1. 有如下 Oracle 存储过程
create or replace procedure proc_out_cursor(
userName in varchar2,
tableCursor out sys_refcursor)
as
begin
open tableCursor for select * from test_user where name = userName;
end;
- 接收的传入参数。
- 通过 OUT 游标传出结果集。
2. 编辑查询语句
{
call proc_out_cursor(#{userName,jdbcType=varchar},
#{tableCursor,mode=cursor,javaType=net.demo.UserDTO})
}
3. 执行存储过程
JdbcTemplate jdbc = ...
Map<String, Object> args = CollectionUtils.asMap("userName", "Kevin");
Map<String, Object> res = jdbc.call(
"{call proc_out_cursor(#{userName,jdbcType=varchar}," +
" #{tableCursor,mode=cursor,javaType=net.demo.UserDTO})" +
"}", args);
List<UserDTO> result = (List<UserDTO>)res.get("tableCursor");
- 使用游标出参数,只需要在普通 OUT 参数配置中设置
mode=cursor即可。
信息
有些数据库在使用游标出参时可能需要将 Connection 设置为事务状态下,具体请详细参考应用程序数据库的使用说明。
函数调用
函数值作为查询列返回时,使用 JdbcTemplate 查询方法接收。例如在 MySQL 中:
Integer value = jdbc.queryForObject("SELECT ABS(?)", new Object[] { -5 }, Integer.class);
返回记录时使用列表或对象查询。JDBC 函数返回参数则通过 callable 语句声明 OUT 参数接收。具体调用语法和返回形式见各数据源的编程式 API 差异。