解决queryForObject查询抛异常的问题

提示:最近在使用Spring的JdbcTemplate简化jdbc开发。在用JdbcTemplate的实例对象调用 queryForObject()方法时,在查询不到时总是抛异常。相信很多初学者都和我有一样的困惑,今天就来解决他。



一、区分queryForObject方法和Query方法

queryForObject方法源码:(查看源码的方法:鼠标放到对应方法上,按ctrl+b)
在这里插入图片描述
有源码可知,首先将sql语句查询到的结果进行封装,放入到list集合中,再去调用并返回DataAccessUtils.requiredSingleResult()方法。(ctrl+b继续深入)
在这里插入图片描述
到这里就清晰了:是依据sql语句查询到的封装到list集合中的数据进行判断返回的。

==0:抛出空结果集异常
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0(大意就是说,正确的结果应该是1,但当前却是0)

>1:抛出不正确的结果集长度异常
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 2(大意就是说,正确的结果应该是1,但当前却是2)

==1:这时候返回结果集的迭代器的next(),即让迭代器的指针指向下一位。
总结:该方法就是进行sql查询后,将所有查询到的结果封装到list集合中,在根据集合的大小,进行返回(正好是1条,就返回该条结果;0或多条就抛出对应异常)
也就是说在不抛异常的情况下返回的是单条结果


query方法源码:
在这里插入图片描述
可以看到该方法返回的是List,显然是list集合,返回的就是sql语句查询到的所有结果

二、如何解决queryForObject方法抛异常的问题

直接的方法就是自己写一个JdbcTemplate的子类。(这样使用自己的MyJdbcTemplate,就不会抛异常了)

/**
 * @Author HYL
 * @Date 2022/8/21 20:58
 * @Version 1.0
 * 重写原生JdbcTemplate中的queryForObject方法,当查到的结果集为0是返回null而不是抛出异常
 * 解决size=0 抛异常的问题
 */

import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;

import javax.sql.DataSource;
import java.util.Collection;
import java.util.List;

public class MyJdbcTemplate extends JdbcTemplate {
    public MyJdbcTemplate(DataSource dataSource){
        super(dataSource);
    }
    @Override
    public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException {
        List<T> results = query(sql, args, new RowMapperResultSetExtractor<T>(rowMapper, 1));
        return requiredSingleResult(results);
    }

    private <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
        int size = (results != null ? results.size() : 0);
        if (size == 0) {
//            throw new EmptyResultDataAccessException(1);
            return null;
        }
        /*
        if (results.size() > 1) {
		 throw new IncorrectResultSizeDataAccessException(1, size);
        }
        */
        //多条时,也返回第一条数据
        return results.iterator().next();
    }
}

连接数据库进行登录验证代码举例:

import com.hyl.demo1.domin.User;
import com.hyl.demo1.utils.JdbcUtil;
import com.hyl.demo1.utils.MyJdbcTemplate;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import java.util.List;


/**
 * @Author HYL
 * @Date 2022/8/21 18:42
 * @Version 1.0
 */
public class UserDao {
    private static MyJdbcTemplate jc=new MyJdbcTemplate(JdbcUtil.getDataSource());
    public static boolean checkLogin(String username,String password){
        String sql="select * from user where username=? and password=?";
        try {
            User user = jc.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
            List<User> users = jc.query(sql, new BeanPropertyRowMapper<>(User.class), username, password);
            System.out.println(user);
            if (user!=null)
                return true;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }
}

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @Author HYL
 * @Date 2022/8/21 18:23
 * @Version 1.0
 */
public class JdbcUtil {
    private static DataSource source=null;
    static {
        Properties properties = new Properties();
        InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(is);
            source= DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取连接池对象
     */
    public static DataSource getDataSource(){
        return source;
    }


    /**
     * 获取连接Connection对象
     */
    public static Connection getConnection() throws SQLException {
        return  source.getConnection();
    }
}

jdbc.properties文件

username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///table_04


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值