提示:最近在使用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