全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-20 分钟 ✍️ juanwangdev

存储过程调用

预计阅读时间: 约 6 分钟

在 MyBatis 中调用数据库存储过程是处理复杂业务逻辑的重要手段。存储过程将一组 SQL 语句预编译并存储在数据库端,通过 CALL 语句即可触发执行,既能减少网络往返,又能利用数据库的执行计划缓存提升性能。

一、CALL 语句基础

1.1 基本语法

MyBatis 通过 statementType="CALLABLE" 声明来调用存储过程,XML 映射文件中使用 {call procedure_name(...)} 格式:

XML
<select id="callProcedure" statementType="CALLABLE">
    {call get_user_stats(#{userId, mode=IN})}
</select>

1.2 statementType 说明

statementType说明适用场景
STATEMENT直接使用 Statement 执行简单静态 SQL
PREPARED使用 PreparedStatement(默认)参数化查询
CALLABLE使用 CallableStatement存储过程调用

要点: 只有 statementType="CALLABLE" 才能正确解析存储过程的参数模式(IN/OUT/INOUT)。

二、CallableStatement 配置

2.1 参数模式设置

存储过程参数需要通过 mode 属性显式声明方向:

XML
<select id="callProc" statementType="CALLABLE">
    {call calculate_salary(
        #{deptId, mode=IN, jdbcType=INTEGER},
        #{totalSalary, mode=OUT, jdbcType=DECIMAL}
    )}
</select>

2.2 常用属性对照

属性必填说明
modeINOUTINOUT,定义参数方向
jdbcType推荐指定 JDBC 类型,避免类型推断错误
javaTypeJava 类型,用于复杂类型映射
typeHandler自定义类型处理器

三、基本参数传递

3.1 纯输入参数调用

XML
<!-- 仅传入参数,存储过程内部处理逻辑 -->
<select id="refreshCache" statementType="CALLABLE">
    {call refresh_user_cache(#{userId, mode=IN, jdbcType=VARCHAR})}
</select>

对应 Java 调用:

Java
public void refreshCache(String userId) {
    session.selectOne("refreshCache", Map.of("userId", userId));
}

3.2 输入 + 输出参数

XML
<select id="getDepartmentStats" statementType="CALLABLE" parameterType="map">
    {call get_dept_stats(
        #{deptId, mode=IN, jdbcType=INTEGER},
        #{empCount, mode=OUT, jdbcType=INTEGER},
        #{avgSalary, mode=OUT, jdbcType=DECIMAL}
    )}
</select>

Java 调用时传入 Map 接收输出参数:

Java
Map<String, Object> params = new HashMap<>();
params.put("deptId", 10);
session.selectOne("getDepartmentStats", params);

Integer empCount = (Integer) params.get("empCount");
BigDecimal avgSalary = (BigDecimal) params.get("avgSalary");

3.3 使用 @Select 注解调用

Java
@Select("{call get_user_by_id(#{userId, mode=IN, jdbcType=INTEGER})}")
@Options(statementType = org.apache.ibatis.mapping.StatementType.CALLABLE)
User getUserById(@Param("userId") Integer userId);

四、要点总结

要点说明
statementType="CALLABLE"调用存储过程必须声明,否则参数模式无法解析
显式声明 modeOUT 和 INOUT 参数必须指定 mode=OUTmode=INOUT
指定 jdbcType避免数据库驱动类型推断失败,特别是 NULL 值场景
输出参数用 Map多 OUT 参数推荐使用 Map 传递,调用后从 Map 取值
返回值处理若存储过程返回结果集,使用 <select> + resultType 接收

存储过程调用是 MyBatis 高级查询的基础,掌握参数传递方式后,可以进一步学习输入输出参数的精细配置和游标结果处理。

📝 发现内容有误?点击此处直接编辑

← 上一篇 复杂查询封装
下一篇 → 游标结果处理
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库