무분별한 SQLException에 대한 처리
우선, 아래 코드를 보자.
// 1. 클라이언트가 전달한 userId로 user 객체 가져옴
try {
user = userDao.findByUserId( req.getParameter("userId") );
} catch (SQLException e) {
e.printStackTrace();
}
// 2. user 객체를 수정함
user.updateUser(
req.getParameter("userId"),
req.getParameter("password"),
req.getParameter("name"),
req.getParameter("email"));
// 3. Db에 다시 업데이트함
try {
userDao.update(user);
} catch (SQLException e) {
e.printStackTrace();
}
SQLException은 컴파일타임 Exception이기 때문에 매번 위와 같이 반드시 try-catch절을 통해서 Exception 처리를 해야 한다. 컴파일타임 Exception은 Checked Exception과 같고, 이에 반대되는 개념으로는 UnChecked Exception이라고 불리우는 런타임 Exception이 있다. 아래 표를 보면서 확인해보자.
구분 | Checked Exception | UnChecked Exception |
확인 시점 | 컴파일(Compile) 시점 | 런타임(Runtime) 시점 |
처리 여부 | 반드시 예외 처리해야 함 | 명시적으로 하지 않아도 됨 |
종류 | IOException, ClassNotFoundException 등 | NullPointerException, ClassCastException 등 |
위 코드에서, SQLException이 발생하면 catch절을 통해서
e.printStackTrace();
가 실행된다.
따라서, SQLException을 catch한다고 해서 에러 로그를 남기는 것외에 별달리 다른 작업을 할 부분이 생각나지 않는다. 컴파일타임 Exception으로 설계하지 않아도 되는 곳에서 컴파일타임 Exception을 사용함으로써 불필요하게 try-catch절로 감싸야하며, 이는 소스코드의 가독성을 떨어트리는 주범이 되고 있다.
SQLException을 런타임 Exception으로 변환해 throw하자.
RuntimeException을 상속하는 커스텀 Exception(DataAccessException과 같은 이름)을 추가한 후 SQLException을 새로 추가한 커스텀 Exception을 변환해 throw 하도록 구현 한다.
RuntimeException을 상속하는 커스텀 Exception
public class DataAccessException extends RuntimeException {
private static final long serialVersionUID = 1L;
public DataAccessException() {
super();
}
public DataAccessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
public DataAccessException(String message) {
super(message);
}
public DataAccessException(Throwable cause) {
super(cause);
}
}
JdbcTemplate 리팩토링
- SQLException이 발생하면 DataAccessException을 던짐.
public class JdbcTemplate{
public void update(String query, PreparedStatementSetter pss) throws DataAccessException {
[...]
} catch (SQLException e) {
throw new DataAccessException();
}
}
public <T> List<T> query(String query, RowMapper<T> rowMapper,
PreparedStatementSetter pss) throws DataAccessException {
[...]
} catch (SQLException e) {
throw new DataAccessException();
} finally {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
throw new DataAccessException();
}
}
}
'Java' 카테고리의 다른 글
[Java] 뷰(View)를 포함한 모델 데이터에 대한 추상화를 담당하는 ModelAndView 구현하기 (0) | 2023.03.29 |
---|---|
[Java] 톰캣(WAS)에서의 URL 패턴과 관련된 이슈 / 자동으로 마지막 슬래시(/)가 추가되어서 리다이렉트 되는 경우 (0) | 2023.03.26 |
[Java] 람다식 / 함수형 인터페이스 / @FunctionalInterface (0) | 2023.03.24 |
[Java] DAO 클래스의 리팩토링(inser, update 쿼리) (0) | 2023.03.22 |
[Java] MVC 프레임워크 구현 (0) | 2023.03.21 |
댓글