如何使用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
相关产品推荐
相关产品推荐

