關於Spring JdbcTemplate調用queryForObject()方法結果集爲空時報異常的解決辦法

JdbcTemplate用的時候發現一個問題:
調用queryForObject()方法,如果沒有查到東西則會拋一個異常:org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
不希望拋出此異常,而是返回爲null就行了。

查看源代碼可知

    @Override
    public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        List<T> results = query(sql, rowMapper);
        return DataAccessUtils.requiredSingleResult(results);
    }

源碼中結果集返回調用了DataAccessUtils的一個靜態方法,在這個靜態方法中spring做了判斷:

    public static <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
        int size = (results != null ? results.size() : 0);
        if (size == 0) {
            throw new EmptyResultDataAccessException(1);
        }
        if (results.size() > 1) {
            throw new IncorrectResultSizeDataAccessException(1, size);
        }
        return results.iterator().next();
    }

我們可以寫一個類直接繼承JdbcTemplate,重寫queryForObject()方法,結果集==0的時候,return null;

public class OverrideJdbc extends JdbcTemplate{

    /**
     * 重寫JdbcTemplate裏面的queryForObject方法源碼調用的requiredSingleResult,當查詢到的結果爲空時返回null(原來是拋出異常)
     */
    @Override
    public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {
        return queryForObject(sql, getSingleColumnRowMapper(requiredType));
    }

    public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        List<T> results = query(sql, rowMapper);
        return requiredSingleResult(results);
    }

    public static <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
        int size = (results != null ? results.size() : 0); 
        if (size == 0) {
            return null; 
        } 
        if (results.size() > 1) {
            throw new IncorrectResultSizeDataAccessException(1, size); 
        } 
        return results.iterator().next(); 
    }
}

然後在spring的配置文件裏爲這個類OverrideJdbc 注入dataSource
【注意】如果你之前用了jdbcTemplate並且在spring配置文件裏面注入了dataSource,你再注入一個就會報如下的錯這裏寫圖片描述

你把jdbcTemplate的bean註釋掉就行了,因爲你寫的OverrideJdbc繼承的jdbcTemplate,它跟jdbcTemplate類型一樣,所以你在用@AutoWired的時候只會識別一個bean,多了或者少了都會報錯,我就是被這個糾結了一下午時間

<!--  <bean id= "jdbcTemplate" class ="org.springframework.jdbc.core.JdbcTemplate">
               <property name= "dataSource" ref ="dataSource"></property>
      </bean> -->

        <!--  配置spring jdbc -->
        <bean id="overrideJdbc" class="com.dao.OverrideJdbc">
               <property name= "dataSource" ref ="dataSource"></property>
        </bean>

配置好之後就可以使用了,當然,jdbcTemplate裏面的其他方法也可以這樣重寫,看個人需求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章