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     }

      

  • 相关阅读:
    java 中类的加载顺序
    jdbc 连接数据库、批量操作、事务(oracle、mysql)
    一个空格引发的血案啊!
    Servlet 的生命周期与线程安全
    Java 方法的重写与重载
    java 序列化
    equals()与hashcode()的理解
    成功安装cadence SPB16.0
    stack implement C++
    windows 7 设置环境变量的方法
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/10431674.html
Copyright © 2011-2022 走看看