1. 程式人生 > >關於Spring JdbcTemplate呼叫queryForObject()方法結果集為空時報異常的解決辦法

關於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裡面的其他方法也可以這樣重寫,看個人需求。