【问题标题】:JdbcTemplate multiple result setsJdbcTemplate 多个结果集
【发布时间】:2013-04-15 12:08:55
【问题描述】:

我试图找到一种简单的方法来处理返回多个结果集的存储过程/SQL。我一直在使用SimpleJdbcOperations#queryForList() 方法,但是这只会将第一个结果集作为List<Map<String, Object>> 返回。我需要能够获得多个结果集,理想情况下是CollectionList<Map<String, Object>> 之类的。我正在编写的程序是一个中间件组件,所以我不知道 SQL 将是什么,也不知道结果集的形式。

我想我必须使用JdbcOperations 类,它可以让我访问更多方法,包括execute(CallableStatementCreator csc, CallableStatementCallback<T> action),但现在我被卡住了。

    CallableStatementCallback<T> callback = new CallableStatementCallback<T>() {
       @Override
       public T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException
       {
           boolean results = cs.execute(request);
           while(results)
           {
               ResultSet result = cs.getResultSet();
               results = cs.getMoreResults();
           }
           return null;
        }
};

我不太确定如何使用该方法,或者如何使用ResultSet 来获得我的通用List&lt;Map&lt;String, Object&gt;&gt;s。

【问题讨论】:

  • A ResultSet 包含在数据库上直接执行 SQL 后会找到的行,它永远不会返回 List&lt;Map&lt;X,Y&gt;&gt;。您必须使用 ResultSet 中的字段自己生成它,您可以使用 getter 访问它。
  • 我应该能够使用hasNext()getObject() 迭代ResultSet
  • 您将使用 while 循环和 next() 并通过各种 getter 获得不同的行字段。
  • 认为我只能使用getObject,因为我不知道ResultSet 会是什么。
  • 你不是写SQL的人吗?我认为您将不得不将其视为某个点。

标签: java jdbc spring-jdbc


【解决方案1】:

我设法使用此代码获得了Set&lt;ResultSet&gt;

private Set<ResultSet> executeProcedure(final String sql)
{
    return jdbc.execute(new CallableStatementCreator() {
        @Override
        public CallableStatement createCallableStatement(Connection con) throws SQLException
        {
            return con.prepareCall(sql);
        }
    }, new CallableStatementCallback<Set<ResultSet>>() {
        @Override
        public Set<ResultSet> doInCallableStatement(CallableStatement cs) throws SQLException
        {
            Set<ResultSet> results = new HashSet<>();

            boolean resultsAvailable = cs.execute();

            while (resultsAvailable)
            {
                results.add(cs.getResultSet());
                resultsAvailable = cs.getMoreResults();
            }
            return results;
        }
    });
}

只是想看看将ResultSet 翻译成List&lt;Map&lt;String, Object&gt;&gt;

【讨论】:

【解决方案2】:

您可以使用 resultSet.getMetaData() 方法来计算出数据中有哪些列:

ResultSetMetaData meta = resultSet.getMetaData();
int colcount = meta.getColumnCount();
for (int i = 1; i <= colcount; i++) 
{
    String name = meta.getColumnLabel(i); // This is the name of the column
    int type = meta.getColumnType(i);     // from java.sql.Types
   // Maybe add to a Map,List, etc...
}

然后您可以像其他评论者提到的那样通过 ResultSet 循环提取您需要的数据:

while (resultSet.hasNext())
{
     resultSet.next();
     // Find the columns you want to extract (via the above method maybe) and add to your row.
}

【讨论】:

  • 很酷,谢谢 :) 我正在寻找一种方法来获取列数。
【解决方案3】:

我使用以下方法以List&lt;Map&lt;String, Object&gt;&gt; 的形式获取 ResultSet 列表

public List<List<Map<String, Object>>> executeProcedure(final String sql) {
        return jdbcTemplate.execute(new CallableStatementCreator() {
            @Override
            public CallableStatement createCallableStatement(Connection con) throws SQLException {
                return con.prepareCall(sql);
            }
        }, new CallableStatementCallback<List<List<Map<String, Object>>>>() {
            @Override
            public List<List<Map<String, Object>>> doInCallableStatement(CallableStatement cs) throws SQLException {
                boolean resultsAvailable = cs.execute();
                List<List<Map<String, Object>>> list = new ArrayList<List<Map<String, Object>>>();
                while (resultsAvailable) {
                    ResultSet resultSet = cs.getResultSet();
                    List<Map<String, Object>> subList = new ArrayList<Map<String, Object>>();
                    while (resultSet.next()) {
                        ResultSetMetaData meta = resultSet.getMetaData();
                        int colcount = meta.getColumnCount();
                        Map<String, Object> map = new HashMap<String, Object>();
                        for (int i = 1; i <= colcount; i++) {
                            String name = meta.getColumnLabel(i);
                            map.put(name, resultSet.getString(i));
                        }
                        subList.add(map);
                    }
                    list.add(subList);
                    resultsAvailable = cs.getMoreResults();
                }
                return list;
            }
        });
    }

【讨论】:

    【解决方案4】:

    此代码在大多数情况下可能更易于使用:

    Map<String,Object> resultSets = new JdbcTemplate(dataSource)
                .call(con -> con.prepareCall(query), new ArrayList<>());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-17
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多