关于Spring JdbcTemplate调用queryForObject()方法结果集为空时报异常的解决办法

本文介绍如何通过继承JdbcTemplate并重写queryForObject方法,来改变Spring JDBC默认的空结果异常行为,使其在查询不到数据时返回null。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值