개발/Spring

Spring Data JPA - 2

IamBD 2022. 2. 25. 17:03

패스트캠퍼스 강의를 보며 정리한 내용입니다.


 

1. @Repository

 

persistence layer를 구현하는 클래스는 @Component와 마찬가지로 해당 클래스를 빈으로 등록해서 사용해야 합니다.

@Repository로 등록을 하게되면 persistence layer에서 발생하는 에러를 DataAccessException으로 Spirng error로

처리해주기 때문입니다.

 

하지만 JPA를 사용할 때 어노테이션 없이 extends 받는것만으로 사용하고 있는데 그 이유는 상속받는 JpaRepository의 구현체를 따라가보면 알 수 있습니다

 

따라서 Spring Data JPA를 사용하게 될 경우 직접 @Repository 어노테이션을 사용할 일은 없다고 봐도 무방합니다.

 

JpaRepository의 상속 관계는 다음과 같습니다
  1. Repository - 아무 메소드도 제공하지 않음.
  2. CrudRepository => Repository + 기본적인 CURD 기능 제공
  3. PagingAndSortingRepository => CrudRepository + 페이징, 정렬 기능 제공
  4. JpaRepository => PagingAndSortingRepository + Spirng Data JPA repository 전체 기능 제공

 

Spring Data JPA에서는 쿼리 메서드를 이용해 데이터를 조작할 수 있습니다.

즉, 인터페이스에 작성한 메소드의 이름이 곧 쿼리의 표현이 됩니다.

 

이벤트 이름과 이벤트 상태를 가지고 특정 이벤트의 리스트를 조회하는 메소드 예시입니다.

List<Event> findByEventNameAndEventStatus(String eventName, EventStatus eventStatus);

이는 SELECT * FROM EVENT WHERE event_name = "eventName" AND event_status = "eventStatus"와 같습니다.

 

단, 쿼리 메서드는 파라미터를 선택적으로 받는 다이나믹 쿼리나 Join을 사용하는 복잡한 쿼리는 지원하지 않습니다.

 

 

 

2. @Entity 디자인

 

Entity 어노테이션은 데이터베이스에 저장할 자바 객체를 정의하며 클래스 내부에서 다양한 어노테이션들을 통해 자세한 테이블 스키마 정보를 표현합니다. 이 때, 어노테이션으로 표현한 스키마 정보와 실제 테이블 스키마가 완벽하게 일치할 필요는 없습니다. 설계된 Entity 클래스는 하나의 도메인으로 간주됩니다.

 

Entity 클래스 내부에서 사용되는 주요 어노테이션은 다음과 같습니다.
  • @Table, @index, @UniqueConstraint : 테이블 기본 정보와 인덱스, unique 키를 설정
  • @Id, @GeneratedValue : primary key 설정
  • @Column : 각 컬럼 설정 (생략 가능하며 세부적인 규칙을 정할 때 사용)
  • @Enumerated : enum을 처리하는 방법을 설정
  • @Transient : 특정 필드를 DB 영속 대상에서 제외
  • @OneToOne, @OneToMany, @ManyToOne, @ManyToMany : 연관 관계 설정
  • @mappedSuperClass : 상속을 이용한 공통 필드 정의
  • @Embedded, @Embeddable : 클래스 멤버를 이용한 공통 필드 정의
  • @DateTimeFormat : 스프링에서 제공하는 어노테이션으로 날짜 입력 포맷을 지정

 

Entity 클래스 예시입니다.
@Entity
public class Event {

    @Setter(AccessLevel.PRIVATE)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @Setter
    @Column(nullable = false)
    private Long placeId;

    @Setter
    @Column(nullable = false)
    private String eventName;

    @Setter
    @Column(nullable = false, columnDefinition = "varchar default 'OPENED'")
    @Enumerated(EnumType.STRING)
    private EventStatus eventStatus;

    @Setter
    @Column(nullable = false, columnDefinition = "datetime")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime eventStartDatetime;

    @Setter @Column(nullable = false, columnDefinition = "datetime")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime eventEndDatetime;

    @Setter @Column(nullable = false, columnDefinition = "integer default 0")
    private Integer currentNumberOfPeople;

    @Setter @Column(nullable = false)
    private Integer capacity;

    @Setter
    private String memo;


    @Column(nullable = false, insertable = false, updatable = false,
            columnDefinition = "datetime default CURRENT_TIMESTAMP")
    @CreatedDate
    private LocalDateTime createdAt;

    @Column(nullable = false, insertable = false, updatable = false,
            columnDefinition = "datetime default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP")
    @LastModifiedDate
    private LocalDateTime modifiedAt;
}

 

line 6 : 기본 key 생성 전략. 예제에서의 IDENTITY는 autoincrement를 의미하며 commit이 아닌 persist에서 DB Insert
line 19 : @columnDefinition은 해당 컬럼의 기본 값 설정
line 42 : insertable과 updatable이 false로 JPA에서 쿼리 생성시 insert문과 update문을 생성하지 않음

 

 

3. DataSource, TransactionManager

3-1 DataSource

물리적인 데이터베이스의 정보를 담는 인터페이스입니다. 하나의 물리 데이터베이스를 표현하며

DataSource의 주요 구현체들은 다음과 같습니다.

  • EmbeddedDatabaseBuilder : HSQL, Derby, H2 등 임베디드 DB 세팅시 사용
  • DataSourceBuilder : JDBC DataSource 빌더
  • DriverManagerDataSource : JDBC 드라이버로 세팅하는 DataSource
  • HikariDataSource : HikariCP를 connection pool로 사용하는 DataSource, Spring Boot 2.x부터 기본 connection pool로 제공되고 있음.

EmbeddedDatabaseBuilder 공식문서

DataSourceBuilder 공식문서

DriverManagerDataSource 공식문서

HikariDataSource 공식문서

 

3-2 TransactionManager

스프링 트랜잭션 관리 기능을 담당하는 인터페이스입니다.

 

TransactionManager의 주요 구현체는 다음과 같습니다.

  • JpaTransactionManager : Spring Data JPA의 기본 구현체로 단일 EntityManagerFactory를 사용
  • DataSourceTransactionManager : 단일 JDBC DataSource를 사용
  • HibernateTransactionManager : 하이버네이트 SessionFactory를 사용

 

3-3 @Transactional

스프링이 제공하는 어노테이션 기반 트랜잭션 관리 기능입니다.

EntityManager를 직접 호출하고 트랜잭션을 적용할 구역을 정하고 롤백을 하는 등의 기능을 대신 수행합니다.

 

특별한 이유가 없는 한 해당 어노테이션을 이용해 모든 트랜잭션을 관리하는것이 바람직합니다.

 

클래스, 메소드 상단에 붙여 간단하게 트랜잭션 구역을 설정하며 동시에 설정시 메소드가 우선시 됩니다.

'개발 > Spring' 카테고리의 다른 글

[Spring] json deserialize ClassCastException  (0) 2022.06.16
InvalidDefinitionException 에러  (0) 2022.06.08
Spring Data JPA - 1  (0) 2022.02.24