지난번에 작성한 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){
}
}
}
}
'백엔드 > 토비의 스프링' 카테고리의 다른 글
[토비의 스프링] 3.3 JDBC 전략 패턴의 최적화 (0) | 2025.05.26 |
---|---|
[토비의 스프링] 3.2 변하는 것과 변하지 않는 것 (0) | 2025.05.25 |
[토비의 스프링] 2.5 학습 테스트로 배우는 스프링 (0) | 2025.05.20 |
[토비의 스프링] 2.4 스프링 테스트 적용 (1) | 2025.05.20 |
[토비의 스프링] 2.3 개발자를 위한 테스팅 프레임워크 JUnit (0) | 2025.05.19 |