패스트캠퍼스 강의를 보며 정리한 내용입니다.
1. @Repository
persistence layer를 구현하는 클래스는 @Component와 마찬가지로 해당 클래스를 빈으로 등록해서 사용해야 합니다.
@Repository로 등록을 하게되면 persistence layer에서 발생하는 에러를 DataAccessException으로 Spirng error로
처리해주기 때문입니다.
하지만 JPA를 사용할 때 어노테이션 없이 extends 받는것만으로 사용하고 있는데 그 이유는 상속받는 JpaRepository의 구현체를 따라가보면 알 수 있습니다
따라서 Spring Data JPA를 사용하게 될 경우 직접 @Repository 어노테이션을 사용할 일은 없다고 봐도 무방합니다.
JpaRepository의 상속 관계는 다음과 같습니다
- Repository - 아무 메소드도 제공하지 않음.
- CrudRepository => Repository + 기본적인 CURD 기능 제공
- PagingAndSortingRepository => CrudRepository + 페이징, 정렬 기능 제공
- 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로 제공되고 있음.
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 |