如何使用带有 Spring RowMapper 的 RowSetDynaClass 来检索 ResultSet 的所有行?

Posted

技术标签:

【中文标题】如何使用带有 Spring RowMapper 的 RowSetDynaClass 来检索 ResultSet 的所有行?【英文标题】:How to use RowSetDynaClass with Spring RowMapper to retrieve all rows of a ResultSet? 【发布时间】:2013-03-29 16:09:26 【问题描述】:

我的 Oracle DB 中有一个存储过程,它返回一个 CURSOR 并且工作正常。我想在没有任何对象持久性的情况下在 Java 中检索游标的数据。我唯一的目标是将其显示到屏幕上。由于我将有几十个存储过程,我不想为每个存储过程创建一个新的 RowMapper,所以我尝试使用 RowSetDynaClass。

我像这样子类化了 Spring StoredProcedure 对象:

public abstract class AbstractReport extends StoredProcedure 

    public static final String KEY_REPORT_RESULT = "profiles";

    public AbstractReport(DataSource dataSource, String sprocName) 
        super(dataSource, sprocName);
        declareParameter(new SqlOutParameter(
                KEY_REPORT_RESULT,
                oracle.jdbc.OracleTypes.CURSOR,
                new RowMapper() 
                    public RowSetDynaClass mapRow(ResultSet argResults, int argRowNum ) throws SQLException 
                        return new RowSetDynaClass(argResults);
                    
                )
        );
//      declareParameter(new SqlOutParameter(
//              "test",
//              oracle.jdbc.OracleTypes.CURSOR,
//              new RowMapper() 
//                  public String[] mapRow(ResultSet argResults, int argRowNum ) throws SQLException 
//                      return new String[]argResults.getString(1), argResults.getString(2), argResults.getString(3);
//                  
//              )
//        );
        compile();
    

    @SuppressWarnings("unchecked")
    public Map<String, Object> computeReport(Map<String, Object> params)
        return super.execute(params);
    
...


这是这样称呼的:

public List<String[]> computeReport(Map<String, Object> params, ReportEnum report) throws EptServiceException 
        List<String[]> result;

        try 
            logger.debug("Computing report " + report);
            AbstractReport procedure = getReport(report);

            Map<String, Object> rawResult = procedure.computeReport(params);
            logger.info("rawResult:" + rawResult);
            result = generateReportOutput(rawResult);
         catch (EptServiceException e) 
            throw e;
         catch (Exception e) 
            logger.error("Error while computing report:" + report, e);
            throw new EptServiceException(EsbPortalError.ERROR_PORTAL_UNKNOWN, e);
        

        return result;
    

除了我从结果中遗漏了一行之外,所有这些都几乎完美无缺... 当我在 SQL 中执行存储过程时,我有 3 个结果。 如果我使用像上面评论中的那样简单的 RowMapper,我会得到 3 个结果。

但是,如果我使用 RowSetDynaClass,我会得到一个有 2 行的对象,而不是预期的 3 行。我知道这没有多大意义(至少它对我没有意义)但是有一定是我错过了一些愚蠢的东西。

我做错了什么?

【问题讨论】:

【参考方案1】:

我终于想通了(大部分)。我找不到使用 RowMapper 接口使其工作的方法。因此,我使用 ResultSetExtractor 对象如下:

declareParameter(new SqlOutParameter(
            KEY_REPORT_RESULT,
            oracle.jdbc.OracleTypes.CURSOR,
            new ResultSetExtractor() 

                @Override
                public Object extractData(ResultSet rs) throws SQLException,
                        DataAccessException 
                    return new RowSetDynaClass(rs);
                
            )
);

这输出了我所期望的正确的三个结果。至于为什么 RowMapper 不起作用,而这个我不知道。

【讨论】:

以上是关于如何使用带有 Spring RowMapper 的 RowSetDynaClass 来检索 ResultSet 的所有行?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Framework应用中JDBC使用RowMapper的一些疑惑

Spring中JdbcTemplate中使用RowMapper

一个加速产生 Spring JDBC RowMapper 的工具类

Spring JDBC RowMapper 用于急切获取

spring 中的 RowMapper

使用 Spring JDBC Rowmapper 映射分层数据