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里面的其他方法也可以这样重写,看个人需求。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud JdbcTemplate是一个用于简化数据库访问的框架,可以方便地进行SQL操作。而分表询是指将数据按照一定的规则拆分到多个表中,通过某种方式进行询。在使用Spring Cloud JdbcTemplate进行分表,可以按以下步骤进行操作: 1. 配置数据源:通过在Spring Boot配置文件中配置数据库连接信息,包括URL、用户名和密码等。可以使用JdbcTemplate的DataSource来获取数据库连接。 2. 创建数据库表:根据分表的规则,创建多个数据库表,并根据需要在表中添加索引等。 3. 定义数据访问对象(DAO):可以创建多个DAO来对应不同的分表,每个DAO中定义相应的询方法。可以使用JdbcTemplate提供的方法来执行SQL语句,并将询结果映射为Java对象。 4. 执行分表询:根据业务需求,编写SQL询语句,并使用JdbcTemplate提供的方法执行询。在,可以根据分表规则动态生成表名,并将询结果返回。 5. 处理询结果:根据需要对询结果进行处理,可以对询结果进行排序、分页等操作。 6. 销毁资源:在使用完JdbcTemplate后,需要销毁相关资源,包括关闭数据库连接等。 总结来说,通过Spring Cloud JdbcTemplate进行分表询的过程是先配置数据源,然后创建数据库表和DAO,最后执行询,并对询结果进行处理。使用JdbcTemplate可以简化数据库访问的过程,提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值