You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JDBI映射存储过程返回的多个结果集?

我之前碰到过一模一样的问题!JDBI默认只会处理存储过程返回的第一个结果集,不过咱们有两种靠谱的办法来搞定多个结果集的映射,给你详细说说:

方法一:手动通过Handle遍历结果集

这种方法灵活性最高,适合需要对不同结果集做不同处理的场景(比如不同结果集映射不同模型)。你可以在DAO方法里注入JDBI的Handle,手动执行语句并遍历所有结果集:

@Dao
public interface TestDao {
    default List<List<TestModel>> getTests() {
        List<List<TestModel>> allResults = new ArrayList<>();
        try (Handle handle = Jdbi.open()) {
            try (Statement stmt = handle.getConnection().createStatement()) {
                // 执行存储过程
                boolean hasMoreResults = stmt.execute("exec test");
                
                // 遍历所有结果集
                while (hasMoreResults) {
                    try (ResultSet rs = stmt.getResultSet()) {
                        // 用JDBI的map方法把当前结果集映射为TestModel列表
                        List<TestModel> currentResult = handle.map(rs, TestModel.class).list();
                        allResults.add(currentResult);
                    }
                    // 检查是否还有下一个结果集
                    hasMoreResults = stmt.getMoreResults();
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException("执行存储过程失败", e);
        }
        return allResults;
    }
}

注意:一定要用try-with-resources语法自动关闭Handle、Statement和ResultSet,避免数据库连接泄漏。

方法二:自定义ResultSetCollector(JDBI 3+适用)

如果你的多个结果集都是同一种模型,或者想更贴合JDBI的注解风格,可以自定义一个ResultSetCollector来收集所有结果集:

首先写自定义的Collector类:

public class MultipleResultSetsCollector<T> implements ResultSetCollector<List<List<T>>> {
    private final RowMapper<T> rowMapper;

    public MultipleResultSetsCollector(RowMapper<T> rowMapper) {
        this.rowMapper = rowMapper;
    }

    @Override
    public List<List<T>> collect(ResultSet resultSet, StatementContext ctx) throws SQLException {
        List<List<T>> allResults = new ArrayList<>();
        boolean hasMoreResults = true;
        
        do {
            List<T> batch = new ArrayList<>();
            // 映射当前结果集的所有行
            while (resultSet.next()) {
                batch.add(rowMapper.map(resultSet, ctx));
            }
            
            if (!batch.isEmpty()) {
                allResults.add(batch);
            }
            
            // 切换到下一个结果集
            hasMoreResults = ctx.getStatement().getMoreResults();
            if (hasMoreResults) {
                resultSet = ctx.getStatement().getResultSet();
            }
        } while (hasMoreResults);
        
        return allResults;
    }
}

然后在DAO接口里使用这个Collector:

@Dao
public interface TestDao {
    @SqlQuery("exec test")
    @RegisterRowMapper(TestModelMapper.class)
    @UseCollector(MultipleResultSetsCollector.class)
    List<List<TestModel>> getTests();
}

这种方法把结果集的收集逻辑封装起来,DAO代码更简洁,适合统一处理同类型结果集的场景。

内容的提问来源于stack exchange,提问作者user3353393

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:26:16