[되새김질] 스프링 DB 1편 - 스프링과 예외 처리, 반복 문제 해결

jeyong·2023년 9월 9일
0

해당 게시물은 인프런 "스프링 DB 1편 - 데이터 접근 핵심 원리" 강의를 참고하여 작성한 글 입니다.

1. 체크 예외와 인터페이스

이번에는 서비스 코드의 예외 의존성을, 런타임 예외로 전환하여 제거해보자.

체크 예외는 인터페이스로의 추상화에서도 발목을 잡는다.

  • 인터페이스의 메서드 선언부에서도 throw 예외를 선언해 주어야하기 때문이다.
  • 이러한 문제 때문에 향후 JDBC가 아닌 다른 기술로 변경한다면 인터페이스 자체를 변경해야 한다.

즉, 인터페이스가 특정 기술의 예외 의존성을 가지게 되어, 추상화의 의미를 퇴색시킨다.
하지만 런타임 예외는 선언을 강제하지 않기 때문에 추상화에 적합하다.

2. 런타임 예외 적용

MemberRepository

MyDbException 이 내부에 SQLException 을 포함하고 있다고 이해하면 된다. 예외를 출력했을 때 스택 트레이스를 통해 둘다 확인할 수 있다

MemberService

  • 메서드에서 throws SQLException 부분이 제거된 것을확인할 수 있다.
  • 드디어 순수한 서비스를 완성했다

남은 문제

현재 하나의 예외만 넘어오기 때문에 예외를 구분할 수 없는 단점이 있다.

3. 데이터 접근 예외 직접 만들기

  • SQLException 내부에 들어있는 errorCode 를 활용하면 데이터베이스에서 어떤 문제가 발생했는지 확인할 수 있다.
  • 해당 정보를 이용하여서 데이터 접근 예외를 직접 만들어보자

MemberRepository 예시

보는 것과 같이 e.getErrorCode() == 23505 : 오류 코드가 키 중복 오류( 23505 )인 경우
MyDuplicateKeyException 을 새로 만들어서 서비스 계층에 던진다.

남은 문제

SQL ErrorCode는 각각의 데이터베이스 마다 다르다. 결과적으로 데이터베이스가 변경될 때 마다
ErrorCode도 모두 변경해야 한다.

4. 스프링 예외 추상화

스프링은 앞서 설명한 문제들을 해결하기 위해 데이터 접근과 관련된 예외를 추상화해서 제공한다.

  • 스프링은 데이터 접근 계층에 대한 수십 가지 예외를 정리해서 일관된 예외 계층을 제공한다
  • 각각의 예외는 특정 기술에 종속적이지 않게 설계되어 있다.

SQLErrorCodeSQLExceptionTranslator

  • translate() 메서드의 첫번째 파라미터는 읽을 수 있는 설명이다.
  • 두번째는 실행한 sql, 마지막은 발생된SQLException 을 전달하면 된다.
  • 이렇게 하면 적절한 스프링 데이터 접근 계층의 예외로 변환해서 반환해준다.

MemberRepository

보는 것과 같이 DI를 이용하여 SQLErrorCodeSQLExceptionTranslator를 주입받고 피라미터들을 넘겨 적절한 예외로 변환받는다.

남은 문제

리포지토리에서 JDBC를 사용하기 때문에 발생하는 반복 문제가 남아있다.

5. JDBC 반복 문제 해결 - JdbcTemplate

지토리의 각각의 메서드를 살펴보면 상당히 많은 부분이 반복된다. 이런 반복을 효과적으로 처리하는 방법이 바로 템플릿 콜백 패턴이다.

JDBC 반복 문제

  • 커넥션 조회, 커넥션 동기화
  • PreparedStatement 생성 및 파라미터 바인딩
  • 쿼리 실행
  • 결과 바인딩
  • 예외 발생시 스프링 예외 변환기 실행
  • 리소스 종료

스프링은 JDBC의 반복 문제를 해결하기 위해 JdbcTemplate 이라는 템플릿을 제공한다.

  • dbcTemplate는 쿼리문의 실행, 커낵션 close등의 작업을 모두 실행해준다.
  • 예외를 자동으로 스프링 예외 변환기를 진행해 주기 때문에 굉장히 편리하다.
profile
천천히 잊어가기

0개의 댓글