zoukankan      html  css  js  c++  java
  • JdbcTemplate中queryForObject方法返回空结果或不正确结果数量的解决方法

      在使用Spirng提供的JdbcTemplate中名为queryForObject API进行数据库查询时有时会抛出如下异常:

    org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

    (不正确的结果大小,预期是1,实际为0)

    或者:

    org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 2 

    (不正确的结果大小,预期是1,实际为2)

      在解决这些异常之前,我们首先来看看queryForObject API的源代码,假设我们调用的是queryForObject(String sql,Class requiredType)。

    JdbcTemplate.class

     1 public <T> T queryForObject(String sql, Class<T> requiredType) 
     2         throws DataAccessException 
     3 {return queryForObject(sql, getSingleColumnRowMapper(requiredType));}
     4 
     5 public <T> T queryForObject(String sql, RowMapper<T> rowMapper) 
     6         throws DataAccessException {
     7     List<T> results = query(sql, rowMapper);
     8     return DataAccessUtils.requiredSingleResult(results);
     9 }
    10 
    11 public <T> List<T> query(String sql, RowMapper<T> rowMapper) 
    12         throws DataAccessException {
    13     return query(sql, new RowMapperResultSetExtractor<T>(rowMapper));
    14 }
    15 
    16 public <T> T query(final String sql, final ResultSetExtractor<T> rse) 
    17         throws DataAccessException {
    18     Assert.notNull(sql, "SQL must not be null");
    19     Assert.notNull(rse, "ResultSetExtractor must not be null");
    20     if (logger.isDebugEnabled()) {
    21         logger.debug("Executing SQL query [" + sql + "]");
    22     }
    23     class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
    24         public T doInStatement(Statement stmt) throws SQLException {
    25             ResultSet rs = null;
    26             try {
    27                 rs = stmt.executeQuery(sql);
    28                 ResultSet rsToUse = rs;
    29                 if (nativeJdbcExtractor != null) {
    30                     rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
    31                 }
    32                 return rse.extractData(rsToUse);
    33             }
    34             finally {
    35                 JdbcUtils.closeResultSet(rs);
    36             }
    37         }
    38         public String getSql() {
    39             return sql;
    40         }
    41     }
    42     return execute(new QueryStatementCallback());
    43 }

    DataAccessUtil.class

     1 public static <T> T requiredSingleResult(Collection<T> results) 
     2         throws IncorrectResultSizeDataAccessException {
     3     int size = (results != null ? results.size() : 0);
     4     if (size == 0) {
     5         throw new EmptyResultDataAccessException(1);
     6     }
     7     if (results.size() > 1) {
     8         throw new IncorrectResultSizeDataAccessException(1, size);
     9     }
    10     return results.iterator().next();
    11 }

      通过阅读源代码,可以清楚地看到在DataAccessUtils.class中requiredSingleResult方法中,当结果集合的size为0或者大于1时,就会抛出以上两个异常。

      解决方法有两个:

      (1)通过修改数据库:删除数据库中对应名称(column)相同的记录,留下只剩"1"条。

      (2)通过更换方法:使用query方法返回list对象(该方法能返回所有查询记录)

    1    public transient List query(String sql, RowMapper rowMapper, Object args[])
    2         throws DataAccessException
    3     {
    4         return (List)query(sql, args, ((ResultSetExtractor) (new RowMapperResultSetExtractor(rowMapper))));
    5     }

      

  • 相关阅读:
    .Net编程接口中的迭代器(转)
    微软,您的.net为中国程序员带来了什么?(转)
    二进制,八进制,十进制,十六进制转换
    简单实现SQL Server2000数据库缓存
    联合查询
    也谈用反射实现Enum→String映射:一种重视性能的方法 (转)
    javascript事件列表解说(转)
    ASP.NET上传控件
    杂杞
    在.net中生成wml
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/10431674.html
Copyright © 2011-2022 走看看