메소드의 정의를 들여다보면 JdbcTemplate 적용 이전에는 있었던 throws SQLException 선언이 적용 후에는 사라졌음을 알 수 있다.
JdbcTemplate 적용 이전
public void deleteAll() throws SQLExcption{
this.jdbcContext.executeSql("delete from users");
}x
JdbcTemplate 적용 이전
public void deleteAll(){
this.jdbcTemplate.eupdate("delete from users");
}
예외를 처리할 때 반드시 지켜야 할 핵심 원칙은 아래와 같다.
모든 예외는 적절하게 복구되든지 아니면 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보돼야 한다.
catch문에 아무것도 안쓰는 건 안됨
system.out.println()이나 log.debug()와 같이 콘솔 이나 로그에 예외메세지만 출력을 해서는 안됨.
Why? SQLException을 예를 들자면, SQLException이 발생하는 이유는 SQL에 문법 에러가 있거나 DB에서 처리할 수 없 을 정도로 데이터 액세스 로직에 심각한 버그가 있거나, 서버가 죽거나 네트워크가 끊 기는 등의 심각한 상황이 벌어졌기 때문이다
굳이 예외를 잡아서 뭔가 조치를 취할 방법이 없다면?
throws Exception이라는, 모든 예외를 무조건 던져버리는 선언을 모든 메소드에 기계적으로 넣는 것이다.
먼저 예외를 처리하는 일반적인 방법을 살펴보고 나서 효과적인 예외처리 전략을 생각 해보겠다.
예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 것이다.
예외를 자신이 처리하지 않고 회피하는 방법이다.
예외처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 것.
throws 문으로 선언해서 예외가 발생하면 알아서 던져지게 하거나 cat ch 문으로 일단 예외를 잡은 후에 로그를 남기고 다시 예외를 던지는 (rethrow) 것.
예외처리를 회피하려면 반드시 다른 오브젝트나 메소드가 예외를 대신 처리할 수 있도록 아래와 같이 던져줘야 한다.
방법 1
public void add() throws SQLException{
//JDBC API
}
방법 2
pulic void add() throws SQLException{
try{
//JDBC API
}catch(SQLException e){
//로그 출력
throws e;
}
}
예외 회피와 비슷하게 예외를 복구해서 정상적인 상태로는 만들 수 없기 때문에 예외를 메소드 밖으로 던지는 것.
학습목표
먼저 생각해볼 사항
스프링의 jdbeTemplate 적용 이후, DAO 메소드에서 SQLException이 모두 사라진 이유?
스프링의 jdbeTemplate은 바로 예외처리 전략을 따르고 있다.
jdbeTemplate의 update(), queryForInt ( ) , quer y( ) 메소드 선언을 잘 살펴보면 모두 throws D ataAccessException이라고 되어 있음.
public int update(final String sql ) throws DataAccessException { ... }
예외 전환의 목적
- 런타임 예외로 포장해서 굳이 필요하지 않은 catch/throws를 줄여주는 것.
- 로우레벨의 예외를 좀 더 의미 있고 추상화된 예외로 바 꿔서 던져주는 것'
DB 종류가 바뀌더라도 DAO를 수정하지 않으려면 두가지 해결방안이있는데, 여기서는 SQLException의 비표준 에러 코드와 SQL 상태정보에 대한 해결책을 알아보자.
학습목표
스프링이 왜 이렇게 D at aA ccessExcept i on 계층구조를 이용해 기술에 독립적인 예외를 정의하고 사용하게 하는지 생각해보자.
DataAccessException은 JDBC의 SQLException을 전환하는 용도로만 만들어진 건 아 니다.
D at aA ccessExcept i on은 의미가 같은 예외라면 데이터 액세스 기술의 종류와 상관없 이 일관된 예외가 발생하도록 만들어준다. 데이터 액세스 기술에 독립적인 추상화된 예 외를 제공하는 것이다.