跳到主要内容

存储过程调用

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 差异。