TIL_220724_강의용 실습 프로젝트 7

창고·2022년 7월 25일
0
post-custom-banner

들어가기에 앞서
실제 프로젝트 진행했던 코드 내용은 업로드하지 않았습니다

12. Spring Data JPA

(1) @Repository

  • persistence layer를 구현하는 클래스에 사용
  • 해당 클래스를 bean으로 등록
  • Spring Data JPA를 사용한다면 "직접 사용할 일은 없다"고 봐도 무방
    (Spring Data JPA가 알아서 구현)

(2) Spring Data JPA 인터페이스

  • 단계별로 필요한 기능까지만 사용 가능
  • Repository : 기본 인터페이스. 어떤 메소드도 제공하지 않음
  • CrudRepository : Repository + CRUD 기능 제공
  • PagingAndSortingRepository : CurdRepository + 페이징, 정렬 기능
  • JpaRepository : PagingAndSortingRepository + Spring Data JPA repository 전체 기능

(3) Query Method

  • 인터페이스에 작성한 메소드 이름이 곧 쿼리 표현이 됨
    • List<Event> findByEventStatusAndEventNameorCapacity(String eventStatus, String eventName, Integer capacity);
    • Optional<Event> findFirstBtEventEndDateTimeBetween(LocalDateTime form, LocalDateTime to);
  • 사용 가능한 키워드가 있음
  • join 등 복잡한 표현은 불가
  • 다이나믹 쿼리는 불가능 (조건, 인자 등의 입력 파라미터가 고정적이지 않고 유동적으로 변하는 쿼리)
  • 실무에서 자주 사용하는 애노테이션
    • @Param : 쿼리 메소드 입력 파라미터에 사용, 애노테이션 기반 파라미터 바인딩 시 사용
    • @Query : 직접 JPQL을 작성하고 싶을 때 사용
    • @NoRepositoryBean : 빈으로 등록하고 싶지 않은 인터페이스를 지정
      • 특정 쿼리 메소드를 기본 메소드로 지정하는 방식으로 운영 가능
      • 특정 메소드를 선택적으로 사용하거나 api에 노출하고자 할 때에도 사용
@NoRepositoryBean
public interface EventReadOnlyRepository extends Repository <Event, Long> {

    Optional<Event> findById(Long id);

(4) @Entity

  • 데이터페이스에 저장(persist)할 자바 객체를 정의
  • 다양한 애노테이션을 이용해 보다 자세한 테이블 스키마 정보를 표현
  • 애노테이션으로 표현한 스키마 정보와 실제 테이블 스키마가 완벽히 일치해야 할 필요는 없음
    (실제 DB보다는 여유롭게, 느슨하게 연결해도 괜찮음)
  • 하나의 도메인으로 간주
  • @Entity 클래스 안에서 사용되는 주요 JPA 애노테이션
    • @Table, @Index, @UniqueConsraint : 테이블 기본 정보와 인덱스, UK를 설정
    • @Id, @GeneratedValue : PK 설정
    • @Column : 각 컬럼 설정
    • @Enumerated : enum을 처리하는 방법을 설정
    • @Transient : 특정 필드를 DB 영속 대상에서 제외
    • @OneToOne, @OneToMany, @ManyToOne, @ManyToMany : 연관 관계 설정
    • @MappedSuperClass : 상속을 이용한 공통 필드 정의
    • @Embedded, @Embeddedable : 클래스 멤버를 이용한 공통 필드 정의
    • @DateTimeFormat : 스프링에서 제공하며 날짜 입력의 포맷을 지정
  • Entity의 Lifecycle Event를 활용한 Auditing 테크닉
    JPA 엔티티에 생성일시, 수정일시 같이 일정하게 작성하는 메타데이터를 처리 가능
    • @PrePersist
    • @PostPersist
    • @PreRemove
    • @PostRemove
    • @PreUpdate
    • @PostUpdate
    • @PostLoad
  • Spring JPA Auditing 애노테이션
    엔티티의 생성일시, 수정일시, 생성자, 수정자를 자동으로 관리해주는 애노테이션
    • 설정 : @EnableJpaAuditing, @EntityListeners(AuditingEntityListener.class)
    • 활용
      • @CreatedBy
      • @CreatedDate
      • @LastModifiedBy
      • @LastModifiedDate

(5) DataSource

  • 물리적인 데이터 소스(DB) 정보를 담는 인터페이스
  • 하나의 물리 DB를 표현
  • 다양한 구현체를 사용
    • EmbeddedDatabaseBuilder : HSQL, Derby, H2 등 임베디드 DB 세팅 시
    • DataSourceBuilder : JDBC DataSource 빌더
    • DriverManagerDataSource : JDBC 드라이버로 세팅하는 DataSource
    • SimpleDriverDataSource : 위를 간편하게 만든 것
    • HikariDataSource : HikariCP를 connection pool로 사용하는 DataSource
    • 그 외

(6) TransactionManager

  • 스프링 트랜잭션 관리 기능을 담당하는 인터페이스
  • 용도에 따라 다양한 인터페이스와 구현체들 존재
    • PlatformTransactionManager, ReactiveTransactionManager
    • JpaTransactionManager : Spring Data JPA 일반적인 상황에 사용하는 구현체
      단일 EntityManagerFactory를 사용
    • DataSourceTransactionManager : 단일 JDBC DataSource를 사용하는 구현체
    • HibernateTransactionManager : 하이버네이트 SessionFactory를 사용하는 구현체
    • ChainedTransactionManager : 여러 개의 트랜잭션 매니저를 묶어서 사용하는 구현체
      (DB, DataSource를 여러 개 사용할 경우 단일 TransactionManager를 여러 개를 동시에 활용할 수 없으므로 묶어서 사용 필요)
      -> 다만 2.5버전 Deprecated되어 대안 필요
  • Java Code로 DataSource, ransactionManager를 수동 세팅해야 하는 경우가 있음
    • configuration properties로 커버되지 않는 세밀한 옵션 필요 시
    • 다중 DataSource
    • 세팅 요소
      • DataSource
      • EntityManagerFactory -> LocalContainerEntityManagerFactoryBean
        추가적인 예외 처리 기능 때문에 인터페이스가 아닌 구현체를 직접 빈으로 등록 필요
      • PlatformTransactionManager
    • 세팅 구성
      • DataSource (DB 설정) -> EntityManagerFactory (JPA 엔티티 관리)
        -> PlatformTransactionManager (트랜잭션 관리)
  • 세팅 예제 JpaConfig
    (https://docs.spring.io/spring-data/jpa/docs/2.5.5/reference/html/#jpa.java-config)
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
class ApplicationConfig {

  @Bean
  public DataSource dataSource() {

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL).build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.acme.domain");
    factory.setDataSource(dataSource());
    return factory;
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}

(7) @Transactional

  • 스프링이 애노테이션 기반 트랜잭션 관리 기능을 제공
  • EntityManager 불러오고 -> 구역 지정하고 -> 커밋 / 롤백 직접 할 필요 없음
  • 서비스 클래스, 메소드에 적용하는 것으로 간단히 트랜잭션 구역을 설정
    • 동시 설정 시 메소드가 우선 순위
  • JpaRepository는 메소드 단위 @Transactional이 이미 붙어 있음
  • 관련 애노테이션
    • 스프링 테스트 지원 애노테이션 : @DataJpaTest와 좋은 조합
      • @Commit
      • @Rollback
    • javax.transaction.@Transactional : 스프링 패키지가 아니므로 주의

(8) @Transactional의 다양한 옵션들

  • transactionManager(value) : 사용할 트랜잭션 매니저를 이름으로 특정
  • label : 트랜잭션을 구분 짓고 식별하는 레이블
  • propagation : 트랜잭션이 중첩될 경우 동작(트랜잭션 효과의 전파) 규칙 (default : REQUIRED)
    • REQUIRED(default) : 현재 있으면 보조, 없으면 새로 만들기
    • SUPPORTS : 현재 있으면 보조, 없으면 트랜잭션 없이 실행
    • MANDATORY : 있으면 보조, 없으면 예외 처리
    • REQUIRES_NEW : 트랜잭션 생성하고 실행, 현재 있던 것은 미룸
    • NOT_SUPPORTED : 트랜잭션 없이 실행, 현재 있던 것은 미룸
    • NEVER : 트랜잭션 없이 실행, 현재 트랜잭션이 있었으면 예외 처리
    • NESTED : 현재 있으면 그 안에서 중첩된 트랜잭션 형성
  • isolation : 트랜잭션 내부 데이터의 격리 레벨 (default : DEFAULT)
    • DEFAULT : DB에게 맡김
    • READ_UNCOMITTED : dirty-read + non-repeatable read + phantom read
    • READ_COMITTED : non-repeatable read + phantom read
    • REPETABLE_READ : phantom read
    • SERIALIZABLE : 완전 직렬 수행
  • timeout, timeoutString : 시간 제한 걸기
  • readOnly : "이 트랜잭션 안에는 select 만 일어난다" 를 표현, 강제성 없으므로 주의
    • 이 옵션을 처리하지 않는 트랜잭션 매니저 구현체 사용 시 별도의 예외 처리를 않음
  • rollbackFor, rollbackForClassName
  • noRollbackFor, noRollbackForClassName
profile
공부했던 내용들을 모아둔 창고입니다.
post-custom-banner

0개의 댓글