백엔드/토비의 스프링
[토비의 스프링] 3.1 다시 보는 초난감 DAO
한뜽규
2025. 5. 21. 23:03
728x90
지난번에 작성한 UserDao를 다시보자.
public void deleteAll() throws SQLException {
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("delete from users");
preparedStatement.executeUpdate();
preparedStatement.close();
connection.close();
}
바로 알겠지만 executeUpdate()에서 에러가 발생하면 connection등의 리소스가 닫히지 않고 메서드가 종료된다.
이렇게 반환되지 않고 connection이 계속 열리게 된다면 서버의 운영 중에 큰 문제가 발생한다.(일반적으로는 커넥션 풀을 사용하지만)
그렇기 때문에 어떤 상황에서도 connection이 닫힐 수 있도록 try/catch/finally 구문을 사용해야 한다.
public void deleteAll() throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement;
try{
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement("delete from users");
preparedStatement.executeUpdate();
preparedStatement.close();
} finally{
if(connection != null){
connection.close();
}
}
}
이렇게 변경해보았다.
만약 connection을 생성하는 도중에 에러가 발생할 수 있고, 그런 connection에서 close()를 호출하면 NPE가 발생하기 때문에 null 체크를 해줘야 한다.
JDBC를 통해서 조회를 하는 경우에는 예외처리가 더 어려워진다.
ResultSet이 추가되기 때문이다.
그렇기 때문에 ResultSet까지 체크하며 닫아주어야 한다.
public int getCount() throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try{
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement("select count(*) from users");
resultSet = preparedStatement.executeQuery();
resultSet.next();
return resultSet.getInt(1);
}finally {
if(resultSet != null){
try{
resultSet.close();
}catch (SQLException ignored){
}
}
if(preparedStatement != null){
try{
preparedStatement.close();
}catch (SQLException ignored){
}
}
if(connection != null){
try {
connection.close();
}
catch (SQLException ignored){
}
}
}
}