關於Spring JdbcTemplate呼叫queryForObject()方法結果集為空時報異常的解決辦法
阿新 • • 發佈:2019-01-22
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裡面的其他方法也可以這樣重寫,看個人需求。