Spring jdbcTemplate查不到数据时抛出EmptyResultDataAccessException

@see https://blog.csdn.net/bbirdsky/article/details/8784434
@see  https://blog.csdn.net/zhang41228/article/details/52799868
问题现象:
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

解决方法:
手动加上try...catch语句块,在catch块中return null,由于这是你业务逻辑代码,spring不会自做主张返回null,万一你没有处理呢?抛出将是空指针异常,反而误导开发者。因此,基于职责单一设计原则,spring抛出异常是合理的(jdbcTemplate的异常都是RuntimeException),它只是负责去查找数据,至于没有找到数据处理逻辑由用户完成。

如果不希望抛出此异常,而是返回为null。

查看源代码可知

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

 源码中结果集返回调用了DataAccessUtils的一个静态方法,在这个静态方法中spring做了判断:

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


我们可以写一个类直接继承JdbcTemplate,重写queryForObject()方法,结果集==0的时候,return null;

  1. public class OverrideJdbc extends JdbcTemplate{  
  2.   
  3.     /** 
  4.      * 重写JdbcTemplate里面的queryForObject方法源码调用的requiredSingleResult,当查询到的结果为空时返回null(原来是抛出异常) 
  5.      */  
  6.     @Override  
  7.     public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {  
  8.         return queryForObject(sql, getSingleColumnRowMapper(requiredType));  
  9.     }  
  10.   
  11.     public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {  
  12.         List<T> results = query(sql, rowMapper);  
  13.         return requiredSingleResult(results);  
  14.     }  
  15.   
  16.     public static <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {  
  17.         int size = (results != null ? results.size() : 0);   
  18.         if (size == 0) {  
  19.             return null;   
  20.         }   
  21.         if (results.size() > 1) {  
  22.             throw new IncorrectResultSizeDataAccessException(1, size);   
  23.         }   
  24.         return results.iterator().next();   
  25.     }  
  26. }  


然后在spring的配置文件里为这个类OverrideJdbc 注入dataSource 
【注意】如果你之前用了jdbcTemplate并且在spring配置文件里面注入了dataSource,你再注入一个就会报如下的错这里写图片描述

你把jdbcTemplate的bean注释掉就行了,因为你写的OverrideJdbc继承的jdbcTemplate,它跟jdbcTemplate类型一样,所以你在用@AutoWired的时候只会识别一个bean,多了或者少了都会报错,我就是被这个纠结了一下午时间

  1. <!--  <bean id= "jdbcTemplate" class ="org.springframework.jdbc.core.JdbcTemplate">  
  2.                <property name= "dataSource" ref ="dataSource"></property>  
  3.       </bean> -->  
  4.   
  5.         <!--  配置spring jdbc -->  
  6.         <bean id="overrideJdbc" class="com.dao.OverrideJdbc">  
  7.                <property name= "dataSource" ref ="dataSource"></property>  
  8.         </bean>  


配置好之后就可以使用了,当然,jdbcTemplate里面的其他方法也可以这样重写,看个人需求。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值