2010-03-09 50 views
3

我們通過Spring SimpleJdbcCall調用pl/sql存儲過程,JdbcTemplate上的fetchsize集被SimpleJdbcCall忽略。儘管我們已經將jdbctemplate的fetchsize設置爲200,但rowmapper結果集獲取大小仍設置爲10.任何想法爲什麼發生這種情況以及如何解決它?SimpleJdbcCall忽略JdbcTemplate獲取大小

在下面的代碼片段中,已經在行映射器中打印了結果集的fetchsize - 一旦它是200,其他時間是10,即使我在兩個occassion中使用相同的JdbcTemplate。

這直接執行通過的JdbcTemplate在行映射

jdbcTemplate = new JdbcTemplate(ds); 
    jdbcTemplate.setResultsMapCaseInsensitive(true); 
    jdbcTemplate.setFetchSize(200); 

    List temp = jdbcTemplate.query("select 1 from dual", new ParameterizedRowMapper() { 
     public Object mapRow(ResultSet resultSet, int i) throws SQLException { 
      System.out.println("Direct template : " + resultSet.getFetchSize()); 
      return new String(resultSet.getString(1)); 
     } 
    }); 

該執行通過SimpleJdbcCall時總是在RowMapper的返回的10 FETCHSIZE返回20​​0 FETCHSIZE

jdbcCall = new SimpleJdbcCall(jdbcTemplate).withSchemaName(schemaName) 
       .withCatalogName(catalogName).withProcedureName(functionName); 
jdbcCall.returningResultSet((String) outItValues.next(), new  ParameterizedRowMapper<Map<String, Object>>() { 
       public Map<String, Object> mapRow(ResultSet rs, int row) throws SQLException { 
        System.out.println("Through simplejdbccall " + rs.getFetchSize()); 
        return extractRS(rs, row); 
       } 
      }); 
outputList = (List<Map<String, Object>>) jdbcCall.executeObject(List.class, inParam); 

回答

4

我不知道怎麼樣ResultSet上的getFetchSize()方法可以信賴得多。 JdbcTemplateStatement上調用setFetchSize(),並假定JDBC驅動程序將對它做正確的事情,包括將其傳播到所有對象。在這種情況下,似乎Oracle JDBC驅動程序不是。

你從兩種方法的不同行爲的原因是,執行一個簡單的SELECT通過JdbcTemplate是簡單的JDBC,而ResultSet你從SimpleJdbcCall回來作爲OUT參數調用獲得。後者更爲複雜,似乎信息正在丟失。

作爲一種解決方法,您是否嘗試過自己撥打ResultSet.setFetchSize()?它可能行不通,但值得一試。您也可以向http://jira.springsource.org/提交問題,看看他們是否認爲Spring的JDBC層可以透明地解決它。

+0

在RowMapper類的mapRow方法中設置ResultSet的提取大小對我來說很有幫助。謝啦! – 2012-09-21 11:19:49

0

不是一個直接的答案,而是一個有用的東西,我認爲。當您手動創建Spring類的對象時,大多數人往往會忘記調用afterPropertiesSet()方法(Spring會調用它來執行任何初始化)。

我檢查了jdbcTemplate.afterPropertiesSet()它似乎只設置異常轉換器和數據源。

2

如果要限制行與Oracle返回的數量,你應該使用子查詢的查詢,並指定啓動和停止ROWNUMBER這樣的:

SELECT * FROM (SELECT ROWNUM as id, demo.* FROM DEMO_TABLE demo) 
WHERE id >= startRowNumber AND id <= stopRowNumber; 

如果你不想任何Oracle特定代碼,您應該考慮使用JPA而不是JDBC:

Query selectQuery = entityManager.createQuery(queryString); 
selectQuery.setMaxResults(maxNumberOfElements); 
selectQuery.setFirstResult(startRowNumber); 
List demoList = entityManager.getResultList(queryString);