Apache DbUtils:处理从存储过程返回的多个结果集
Posted
技术标签:
【中文标题】Apache DbUtils:处理从存储过程返回的多个结果集【英文标题】:Apache DbUtils : Handling multiple result sets returned from Stored Procedure 【发布时间】:2016-08-06 01:04:01 【问题描述】:我在使用 DbUtils 从 SQL Server 中的存储过程中检索结果时遇到问题。
在 SQL Server Management Studio 中执行的存储过程在针对特定输入值执行时返回两个单独的结果集,但对于其他值,它只返回一个结果集。下面的图片说明了这个问题:
返回一个结果集:
返回两个结果集:
我在这里面临的问题是我正在使用 DbUtils BeanListHandler
将结果转换为 UserInfo
bean 的列表。
List<UserInfo> userList = (List<UserInfo>) run.query(STORED_PROC, new BeanListHandler(UserInfo.class), refId);
当存储过程只返回一个结果集时,它工作正常。 但是,在返回两个结果集的情况下,它只给出第一个结果集的列表。
我认为通过使用 JDBC,我们可以使用多个 ResultSet
,但我不确定如何处理这个 DbUtils。
有人可以提供见解吗?如果需要任何其他信息,请更新我,我会提供。
【问题讨论】:
谁能帮忙。我不清楚我的查询吗? 能把存储过程的内容贴出来吗? @Dave 我无法访问存储过程中的查询。我只能执行它以获得结果。 您是否考虑过将org.apache.commons.dbutils.QueryRunner
子类化并用使用PreparedStatement#getMoreResults()
的代码覆盖适当的.query
方法?
@GordThompson 感谢您的指点 (y) 将调查它
【参考方案1】:
说实话,如果该存储过程在一次执行中返回 2 个结果集,那么问题就更大了。理想情况下,您希望从 SP 将 2 个结果作为单个表结果返回,然后您应该没问题。
1) 尝试联系有权访问 SP 的人员,并让他们注意您的情况。让他们创建一个临时表来存储返回的 2 个结果中的所有记录,然后只返回该临时表中的所有内容。
2) 如果您没有该选项,您可以尝试本文retrieve-data-from-stored-procedure-which-has-multiple-result-sets 中概述的过程以获取结果,如果您无法从 1) 中获得任何移动
HTH
戴夫
【讨论】:
感谢您的回答。我尝试使用本机 Jdbc 并使用多个结果集,但该代码很长。有什么方法或类似于 Dbutils 的 Api 我们可以将其更改为使用 Beans/Pojo 的快速代码【参考方案2】:继承QueryRunner
对象然后调整适当的query
方法来处理多个结果集就足够简单了。使用以下代码,我能够使用
UserInfo
对象的完整列表
ResultSetHandler<List<UserInfo>> h = new BeanListHandler<UserInfo>(UserInfo.class);
MyQueryRunner run = new MyQueryRunner(ds);
String sql =
"EXEC dbo.Gain_Web_GetCompanyRepByIndRefID @RefID=?";
List<UserInfo> result = run.query(sql, h, 2);
MyQueryRunner
在哪里
package com.example.so36623732;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
public class MyQueryRunner extends QueryRunner
public MyQueryRunner(DataSource ds)
super(ds);
/**
* Executes the given SELECT or EXEC SQL query and returns a result object.
* The <code>Connection</code> is retrieved from the
* <code>DataSource</code> set in the constructor.
* @param <T> The type of object that the handler returns
* @param sql The SQL statement to execute.
* @param rsh The handler used to create the result object from
* the <code>ResultSet</code>.
* @param params Initialize the PreparedStatement's IN parameters with
* this array.
* @return An object generated by the handler.
* @throws SQLException if a database access error occurs
*/
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException
Connection conn = this.prepareConnection();
return this.<T>query(conn, true, sql, rsh, params);
/**
* Calls query after checking the parameters to ensure nothing is null.
* @param conn The connection to use for the query call.
* @param closeConn True if the connection should be closed, false otherwise.
* @param sql The SQL statement to execute.
* @param params An array of query replacement parameters. Each row in
* this array is one set of batch replacement values.
* @return The results of the query.
* @throws SQLException If there are database or parameter errors.
*/
@SuppressWarnings("unchecked")
private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params)
throws SQLException
if (conn == null)
throw new SQLException("Null connection");
if (sql == null)
if (closeConn)
close(conn);
throw new SQLException("Null SQL statement");
if (rsh == null)
if (closeConn)
close(conn);
throw new SQLException("Null ResultSetHandler");
PreparedStatement stmt = null;
ResultSet rs = null;
T result = null;
List<T> allResults = null;
try
stmt = this.prepareStatement(conn, sql);
this.fillStatement(stmt, params);
rs = this.wrap(stmt.executeQuery());
allResults = (List<T>)rsh.handle(rs);
while (stmt.getMoreResults())
rs = stmt.getResultSet();
result = rsh.handle(rs);
allResults.addAll((List<T>)result);
catch (SQLException e)
this.rethrow(e, sql, params);
finally
try
close(rs);
finally
close(stmt);
if (closeConn)
close(conn);
return (T) allResults;
【讨论】:
太棒了。谢谢:)以上是关于Apache DbUtils:处理从存储过程返回的多个结果集的主要内容,如果未能解决你的问题,请参考以下文章