MyBatis 调用 Oracle 存储过程返回空数据排查

文章目录

    在用 MyBatis 调用 Oracle 存储过程时,遇到返回空数据的情况。排查了半天。。。

    报错

    [debug,137] - ==> Preparing: {call some_procedure( ?, ?, ?, ?, ?, ?, ? )}
    [debug,137] - ==> Parameters: 2(String), 1(String), 2026-07-21 21:29:53(String), 2026-07-22 21:29:53(String), A(String), B(String)
    ERROR [internalAfterStatementExecute,518] - slow sql 5089 millis. {call some_procedure(
                ?,
                ?,
                ?,
                ?,
                ?,
                ?,
                ?
            )} ["2","1","2026-07-21 21:29:53","2026-07-22 21:29:53","A","B"]
    [debug,49] - Closing non transactional SqlSession
    

    返回空。但是在 SQL developer 中调用,返回正常,有返回数据。
    而且 MyBatis 开启了 Trace 日志级别,也看不到任何返回信息。

    Oracle SQL developer 中调用

    var cur refcursor;
    begin
      some_procedure('2','1','2026-07-21 21:29:53','2026-07-22 21:29:53','A','B',:cur);
    end;
    /
    print :cur;
    

    显示

    121 rows selected.
    

    解决方案

    出现这个问题的原因是:对于 Oracle 中返回游标(CURSOR)作为 OUT 参数的存储过程,MyBatis 不会直接将结果集作为 Mapper 方法的返回值返回,而是将结果集封装到一个 List 中并放入你传入的 Map 参数对象里(key 为你在 XML 中配置的 result)。

    之前代码尝试直接通过 someMapper.list(params) 接收返回值,因此返回了空。

    不再直接 return someMapper.list(params);,而是改为从传入的 params 这个 Map 中提取 result 键对应的值,即转换为 List。修改了 SomeMapper.java:将 list 方法返回值改为了 void,消除歧义,强调调用存储过程的结果应该从 params 中读取。

    git diff

    mapper 文件:

    -    public List<SomeVO> list(Map<String, Object> params);
    +    public void list(Map<String, Object> params);
    

    impl 文件:

    -        return someMapper.list(params);
    +        someMapper.list(params);
    +        List<SomeVO> result = (List<SomeVO>) params.get("result");
    +        return result != null ? result : new java.util.ArrayList<>();
    

    警告信息

    // List<SomeVO> result = (List<SomeVO>) params.get("result");
    
    Type safety: Unchecked cast from Object to List<SomeVO>
    

    params.get(“result”) 是从 MyBatis CALLABLE 存储过程 OUT 游标参数取出的 Object,类型只能在运行时确定,因此无法做真正的编译期类型检查。

    最规范的修复是在执行该强制转换的方法上添加 @SuppressWarnings(“unchecked”) 注解

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式