728x90
반응형
SMALL
자바예외
예외 계층
예외 기본 규칙
예외는 잡아서 처리하거나 던져야한다.
예외를 잡거나 던질ㄷ 때 지정한 예외뿐만 아니라 하위 예외까지 함께 처리된다.
체크예외 VS 언체크예외 (런타임예외)
체크예외
체크예외는 예외를 잡아서 처리할 수 없을 때, 예외를 밖으로 던지는 'throw'를 반드시 선언해야한다. 그렇지 않으면 컴파일 오류가 발생언체크예외 (런타임예외)
예외를 잡아서 처리하지 않아도 'throw'를 생략할 수 있다.언체크예외를 사용해야하는 이유
- 복구 불가능한 예외
예를들면 SQLException 예외는 데이터베이스에서 발생하는 예외이다.
이런 예외는 서비스나 컨트롤러에서는 처리가 불가능하다.
따라서 이런 문제들을 일관성있게 공통으로 처리해야한다. - 의존 관계에 대한 문제
예를들면 마찬가지로 SQLException 예외를 서비스나 컨트롤러에서 처리가 불가능한데 해당 예외인 SQLException을 의존까지해야한다.
결과적으로 OCP,DI를 통해 코드의 변경없이 대상 구현체를 변경이 불가능해진다. - 물론 예외의 상위인Exception을 던지면 가능하지만, 이럴 경우 모든
예외가 다 던지기ㄷ 때문에 의도한 사용방법이 아니다.기본적으로는 언체크예외(런타임예외)를 사용한다. 체크예외는 로직상 의도적으로 던지는 예외에만 사용
- 복구 불가능한 예외
체크예외 -> 언체크예외(런타임예외) 전환
static class Repository { public void call() { try { runSQL(); } catch (SQLException e) { //기존예외 e 포함 throw new RuntimeSQLException(e); } } //체크예외 SQLException private void runSQL() throws SQLException { throw new SQLException("ex"); } } //언체크예외(런타임예외) SQLException static calss RuntimeSQLException extends RuntimeExcepiton { public RuntimeSQLException(){ } //기존예외 포함 생성자 public RuntimeSQLException(Throwable cause){ super(cause); } }
체크예외와 인터페이스
MyDbException 런타임 예외
public class MyDbException extends RuntimeException{
public MyDbException() {
}
public MyDbException(String message) {
super(message);
}
public MyDbException(String message, Throwable cause) {
super(message, cause);
}
public MyDbException(Throwable cause) {
super(cause);
}
}
리포지토리
* 예외 누수 문제 해결
* 체크예외를 런타임 예외로 변경
* MemberRepository 인터페이스 사용
* throws SQLException 제거
public class MemberRepositoryV4_1 implements MemberRepository{
private final DataSource dataSource;
public MemberRepositoryV4_1(DataSource dataSource) {
this.dataSource = dataSource;
}
public Member save(Member member) {
String sql = "insert into member(member_id,money) values (?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
return member;
} catch (SQLException e) {
//SQLException을 MyDbException이라는 런타임예외로 변환
throw new MyDbException(e);
} finally {
close(con,pstmt, null);
}
}
}
스프링 예외 추상화 이해
스프링은 데이터 접근과 관련된 예외를 추상화해서 제공한다.
해당 추상화를 사용하면 JDBC나 JPA 어떤 기술을 사용하든 스프링이 제공하는 예외를 사용하면 된다.
JDBC나 JPA를 사용시에 발생하는 예외를 스프링이 제공하는 예외로 변환해주는 역할도 제공SQLExceptionTranslator 추가 public class MemberRepositoryV4_2 implements MemberRepository{ private final DataSource dataSource; //스프링이 제공하는 SQL예외 변환기 private final SQLExceptionTranslator exTranslator; public MemberRepositoryV4_2(DataSource dataSource) { this.dataSource = dataSource; this.exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource); } @Override public Member save(Member member) { String sql = "insert into member(member_id,money) values (?, ?)"; Connection con = null; PreparedStatement pstmt = null; try { con = getConnection(); pstmt = con.prepareStatement(sql); pstmt.setString(1, member.getMemberId()); pstmt.setInt(2, member.getMoney()); pstmt.executeUpdate(); return member; } catch (SQLException e) { //"save" 해당 예외에 대한 설명 //sql 실행한 sql //e 마지막에 발생된 SQLException throw exTranslator.translate("save", sql, e); } finally { close(con,pstmt, null); } } }
JDBC Template
스프링은 JDBCD의 반복 문제를 해결하기 위해 템플릿을 제공
JDBCTemplate 사용 리포지토리 public class MemberRepositoryV5 implements MemberRepository{ //JDBC Template 사용 private final JdbcTemplate template; public MemberRepositoryV5(DataSource dataSource) { this.template = new JdbcTemplate(dataSource); } @Override public Member save(Member member) { String sql = "insert into member(member_id,money) values (?, ?)"; // template.update(sql, member.getMemberId(), member.getMoney()); return member; } }
728x90
반응형
LIST
'Spring' 카테고리의 다른 글
Spring JPA (1) (0) | 2024.09.30 |
---|---|
Spring DB 데이터 접근 기술 (0) | 2024.09.30 |
Spring DB 트랜잭션 (0) | 2024.09.30 |
Spring DB JDBC (0) | 2024.09.30 |
Spring MVC 파일업로드 (2) | 2024.09.30 |