【问题标题】:SimpleJdbcCall ignoring JdbcTemplate fetch sizeSimpleJdbcCall 忽略 JdbcTemplate 获取大小
【发布时间】:2011-01-25 07:44:55
【问题描述】:

我们通过 Spring SimpleJdbcCall 调用 pl/sql 存储过程,在 JdbcTemplate 上设置的 fetchsize 被 SimpleJdbcCall 忽略。尽管我们已将 jdbctemplate fetchsize 设置为 200,但 rowmapper 结果集获取大小设置为 10。知道为什么会发生这种情况以及如何解决它吗?

已经在下面的代码 sn-p 中的 rowmapper 中打印了结果集的 fetchsize - 一旦它是 200,其他时候它是 10,即使我在这两种情况下都使用相同的 JdbcTemplate。

这种通过 jdbctemplate 直接执行在行映射器中返回 fetchsize 200

    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

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);

【问题讨论】:

    标签: java database spring stored-procedures jdbc


    【解决方案1】:

    我不确定ResultSet 上的getFetchSize() 方法有多少可信度。 JdbcTemplateStatement 上调用 setFetchSize(),并假设 JDBC 驱动程序会用它做正确的事情,包括将它传播到所有 ResultSet 对象。在这种情况下,Oracle JDBC 驱动程序似乎不是。

    您从这两种方法获得不同行为的原因是执行简单的SELECTJdbcTemplate 是简单的 JDBC,而您从SimpleJdbcCall 返回的ResultSet 是作为调用的 OUT 参数获得的.后者更复杂,似乎信息正在丢失。

    作为一种解决方法,您是否尝试过自己致电ResultSet.setFetchSize()?它可能行不通,但值得一试。您也可以向http://jira.springsource.org/ 提交问题,看看他们是否认为 Spring 的 JDBC 层可以透明地解决它。

    【讨论】:

    • 在 RowMapper 类的 mapRow 方法中设置 ResultSet 的获取大小对我来说是一种享受。谢谢大佬!
    • mapRow 为结果集中的每一行调用,它不是正确的位置。应该在调用 rs.next() 之前设置获取大小
    【解决方案2】:

    如果你想限制 Oracle 返回的行数,你应该使用子选择查询并像这样指定开始和停止行号:

    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);
    

    【讨论】:

    • SimpleJdbcCall 用于调用存储的过程和函数,客户端对 sql 不可见。
    【解决方案3】:

    不是一个直接的答案,但我认为这是一件有用的事情。当您手动创建 Spring 类的对象时,大多数人往往会忘记调用 afterPropertiesSet() 方法(由 Spring 调用以执行任何初始化)。

    我检查了 jdbcTemplate.afterPropertiesSet() 它似乎只设置了异常转换器和数据源。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2020-10-05
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-08
      • 2021-05-18
      • 2016-10-03
      相关资源
      最近更新 更多