UserDao의 문제점
- 예외 처리에 대한 문제
3.1.1 예외처리 기능을 갖춘 DAO
JDBC 코드에서 반드시 지켜야 할 원칙
- 예외처리 : 예외가 발생할 경우, 사용한 리소스를 반드시 반환하여야 한다.
JDBC 수정 기능의 예외처리 코드
UserDao의 deleteAll()
- Connection과 PreparedStatement라는 두 개의 공유 리소스를 가져와서 사용
- close()를 이용하여 리소스를 반환
- 중간에 예외가 발생할 경우 close()가 실행되지 않아 리소스가 반환되지 않음
try/catch/finally 구문을 이용한 deleteAll()
public void deleteAll() throws SQLException {
Connection c = null;
PreparedStatement ps = null;
try {
c = dataSource.getConnection();
ps = c.prepareStatement("DELETE FROM users WHERE 1=1");
ps.executeUpdate();
} catch (SQLException e) {
throw e;
} finally {
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
}
}
}
}
예외상황에서도 안전한 코드
- finally : try 블록 수행 후 예외와 상관없이 반드시 실행되는 코드
- 예외 발생 시점에 따라 c.close()와 ps.close() 중 어떤 메소드를 호출해야 할 지 달라짐
- 반드시 c와 ps가 null인지 아닌지 확인 후 close()를 호출해야함
- close() 역시 예외 발생 가능한 메소드이므로 try/catch로 처리
JDBC 조회 기능의 예외처리
조회를 위한 JDBC의 경우, ResultSet이 추가되므로 좀 더 복잡해진다.
getCount()
public int getCount() throws SQLException{
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
int count = 0;
try {
c = dataSource.getConnection();
ps = c.prepareStatement("SELECT COUNT(*) FROM users");
rs = ps.executeQuery();
rs.next();
count = rs.getInt(1);
} catch (SQLException e) {
throw e;
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
}
}
}
return count;
}
Question
1. 책에서는 try문에서 바로 return 하는데 return 해도 finally 구문을 수행하는가
2. count 초기값을 0으로 줘도 괜찮을까? (테스트)
초난감 DAO의 오명에서 벗어났다.
- 예외상황에 대한 처리
- 서버환경에서도 안정적으로 수행
- DB 연결 기능을 자유롭게 확장할 수 있는 이상적인 DAO
- 실전에 적용해도 문제가 없는 DAO
그러나 여전히 아쉬움이 남아있다.
' Spring > 토비의 스프링 3.1' 카테고리의 다른 글
3.3 JDBC 전략 패턴의 최적화 (0) | 2019.01.18 |
---|---|
3.2 변하는 것과 변하지 않는 것 (0) | 2019.01.18 |
3.0 템플릿 (0) | 2019.01.17 |
2.6 정리 (0) | 2019.01.17 |
2.5 학습 테스트로 배우는 스프링 (0) | 2019.01.17 |