Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

[Spring 레퍼런스] 12장 DAO 지원

이 문서는 개인적인 목적이나 배포하기 위해서 복사할 수 있다. 출력물이든 디지털 문서든 각 복사본에 어떤 비용도 청구할 수 없고 모든 복사본에는 이 카피라이트 문구가 있어야 한다.



12. DAO 지원

12.1 소개
스프링의 Data Access Object (DAO) 지원은 JDBC, Hibernate, JPA, JDO같은 데이터 접근 기술과 관련된 작업을 일관된 방법으로 쉽게 할 수 있게 도와준다. DAO 지원은 앞서 언급한 퍼시스턴스 기술을 꽤 쉽게 해주고 각 기술에 특화된 익셉션 처리에 대해 걱정하지 않고 코드를 짤 수 있게 해준다.


12.2 일관된 예외 계층
스프링은 SQLException처럼 기술에 특화된 예외를 루트 익셉션처럼 DataAccessException의 스프링 예외계층으로 편리하게 변환한다. 이러한 예외는 원래의 예외를 감싸므로 잘못되거나 정보를 잃어버릴 위험이 절대 없다.

JDBC 예외에 추가적으로 스프링은 소유자로부터 변환해서 하이버네이트에 특화된 예외와 체크드 익셉션(하이버네이트 3.0 이전의 버전인 경우)을 관심있는(focused) 런타임 예외(JDO와 JPA 예외에도 마찬가지다.)의 세트로 감쌀 수 있다. 이는 복구할 수 없고 적합한 계층에서만 존재하고 보일러플레이트 catch-throw 블락을 귀찮음없으면서 DAO에 선언된 예외인 대부분의 퍼시스턴스 예외를 처리하게 해준다. (여전히 필요한 곳에서는 예외를 처리할 수 있다.) 앞에서 얘기했듯이 JDBC 예외(데이터베이스에 특화된 방언을 포함해서)도 같은 계층 즉 일관된 프로그래밍 모델에서 JDBC로 작업을 수행할 수 있는 계층으로 변환할 수 있다.

스프링의 다양한 템플릿 클래스는 다양한 ORM 프레임워크를 지원한다. 인터셉터 기반의 클래스를 사용한다면 어플리케이션은 되도록이면 SessionFactoryUtils의 convertHibernateAccessException(..)나 convertJdoAccessException()에 각각 위임해서 HibernateExceptions와 JDOExceptions 자체를 다루는 데 신경써야 한다. 이 메서드들은 예외를 org.springframework.dao 예외 계층의 예외와 호환되도록 변환한다. JDOExceptions가 언체크드면 예외와 관련된 용어로 제너릭 DAO 추상화를 희생시켜서 그냥 던질 수 있다.

스프링이 제공하는 예외 계층은 아래에서 볼 수 있다. (이미지의 클래스 계층은 전체 DataAccessException 계층의 서브세트만 보여준다.)

사용자 삽입 이미지



12.3 DAO나 리파지토리 클래스 설정에 사용하는 어노테이션
데이터 접근 객체(DAO)나 리파지토리가 예외 변환을 제공한다는 것을 보장하는 가장 좋은 방법은 @Repository 어노테이션을 사용하는 것이다. 이 어노테이션은 컨포넌트 스캔이 XML 설정없이도 DAO와 리파지토리를 찾고 설정하도록 해준다.


@Repository
public class SomeMovieFinder implements MovieFinder {
  // ...
}

모든 DAO와 리파지토리 구현체는 사용하는 퍼시스턴스 기술에 따라 퍼시스턴스 리소스에 접근해야할 필요가 있을 것이다. 예를 들어 JDBC 기반 리파지토리는 JDBC DataSource에 접근할 것이고 JPA 기반 리파지토리는 EntityManager에 접근해야 할 것이다. 이렇게 하는 가장 쉬운 방법은 @Autowired,, @Inject, @Resource, @PersistenceContext 어노테이션 중에 하나를 사용해서 해당 리소스를 의존성 주입하는 것이다. 다음은 JPA 리파지토리의 예제이다.

@Repository
public class JpaMovieFinder implements MovieFinder {
  @PersistenceContext
  private EntityManager entityManager;

  // ...
}

전형적인 하이버네이트 API를 사용한다면 SessionFactory를 주입할 수 있다.

@Repository
public class HibernateMovieFinder implements MovieFinder {

  private SessionFactory sessionFactory;
  
  @Autowired
  public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
  }
  
  // ...
}

이번 장에서 보여줄 마지막 예제는 대표적인 JDBC 지원이다. DataSource를 사용하는 SimpleJdbcCall 등과 같은 데이터 접근 지원 클래스나 JdbcTemplate를 생성하하는 곳에 초기화 메서드에 이 DataSource를 주입할 것이다.

@Repository
public class JdbcMovieFinder implements MovieFinder {

  private JdbcTemplate jdbcTemplate;
  
  @Autowired
  public void init(DataSource dataSource) {
      this.jdbcTemplate = new JdbcTemplate(dataSource);
  }
  
  // ...
}

Note
이러한 어노테이션의 이점을 취하기 위해 어플리케이션 컨텍스트를 설정하는 방법은 각 퍼시스턴스 기술의 해당하는 부분을 참고하길 바란다.

2012/12/13 23:30 2012/12/13 23:30