객체와 테이블 매핑
@Entity
- JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙여야 하며, @Entity가 붙은 클래스를 엔티티라고 한다.
- JPA는 엔티티 객체를 생성할 때 기본 생성자를 사용하기 때문에, 파라미터가 없는 public 또는 protected 생성자를 필수로 지정해주어야 한다.
- @Entity 어노테이션은 final, enum, interface, inner 클래스에는 사용할 수 없으며, 저장할 필드에도 final을 사용하면 안 된다.
@Table
- @Table은 엔티티와 매핑할 테이블을 지정하며, 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.
- @Table 어노테이션에 uniqueConstraint 속성을 지정하면 DDL 생성 시에 유니크 제약조건을 지정할 수 있다.
스키마 자동 생성
- JPA는 클래스의 매핑정보와 데이터베이스 방언을 사용해서 데이터베이스 스키마를 자동으로 생성하는 기능을 제공한다.
- 스키마 자동 생성 기능을 사용하려면 jpa.hibernate.ddl-auto 속성을 이용한다.
jpa:
hibernate:
# 어플리케이션 실행 시점에 테이블을 drop 하고 다시 생성
ddl-auto: create
create | 기존 테이블을 삭제하고 새로 생성한다. |
create-drop | create 속성에 추가로 애플리케이션을 종료할 때 생성한 DDL을 제거한다. |
update | 데이터베이스 테이블과 엔티티 매핑정보를 비교해서 변경 사항만 수정한다. |
validate | 데이터베이스 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 애플리케이션을 실행하지 않는다. |
기본키 매핑
직접 할당
- 기본키 직접 할당 전략은 em.persist()로 엔티티를 저장하기 전에 애플리케이션에서 기본키를 직접 할당하는 방법으로, 식별자 값없이 저장하면 예외가 발생한다.
- @Id 어노테이션을 사용하며, 가능한 타입은 자바 기본형, 자바 래퍼형, String, Date, BigDecimal, BinInt
- 비즈니스 요구사항은 계속해서 변하는데 테이블은 한 번 정의하면 변경하기 어렵기 때문에 JPA는 모든 엔티티에 일관된 방식으로 대리키 사용을 권장한다.
자동 생성
- 기본키를 데이터베이스가 생성해주는 값(대리키)으로 사용하는 방식으로 @Id에 @GeneratedValue 어노테이션을 사용해서 식별자 생성 전략을 선택한다.
IDENTITY | 기본키 생성을 데이터베이스에 위임한다. |
SEQUENCE | 데이터베이스 시퀀스를 사용해서 기본키를 할당한다. |
TABLE | 키 생성 테이블을 사용한다. |
IDENTITY
- 기본키 생성을 데이터베이스에 위임하는 전략으로 주로 MySQL에서 사용하는 방식
- IDENTITY 식별자 생성 전략은 엔티티를 데이터베이스에 저장해야 식별자를 구할수 있기 때문에, 엔티티를 영속 상태로 만들기 위해 em.persist()를 호출하는 즉시 INSERT SQL이 데이터베이스에 전달된다.
- 따라서 IDENTITY 전략은 트랜잭션을 지원하는 쓰기 지연이 동작하지 않는다.
SEQUENCE
- 데이터베이스 시퀀스를 사용해서 기본키를 생성하는 방식으로 오라클, PostgreSQL처럼 시퀀스를 지원하는 데이터베이스에서 사용할 수 있다.
- 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트
- SEQUENCE 전략은 em.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회하고, 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다.
- 이후 트랜잭션을 커밋해서 플러시가 일어나면 엔티티를 데이터베이스에 저장한다.
TABLE
- 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략으로, 모든 데이터베이스에 적용할 수 있다.
- 시퀀스 대신에 테이블을 사용한다는 것만 제외하면 SEQUENCE 전략과 내부 동작 방식은 동일하다.
- 즉, 시퀀스 생성용 테이블에서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다.
AUTO
- 선택한 데이터베이스 방언에 따라 세 전략 중 하나를 자동으로 선택한다.
- 데이터베이스를 변경해도 코드를 수정할 필요가 없다는 장점 때문에, 키 생성 전략이 아직 확정되지 않은 개발 초기나 프로토타입 개발 시에 사용한다.
- AUTO를 사용할 때 SEQUENCE나 TABLE 전략이 선택되면 시퀀스나 키 생성용 테이블을 미리 만들어 두어야 하며, 만약 스키마 자동 생성 기능을 사용한다면 하이버네이트가 기본값을 이용해서 적절한 시퀀스나 키 생성용 테이블을 만들어 준다.
필드와 컬럼 매핑
@Column
- 객체 필드와 테이블 컬럼을 매핑한다.
- 자바 기본 타입에는 null 값을 입력할 수 없기 때문에, 자바 기본 타입에 @Column을 사용할 경우 not null 제약조건을 추가하는 것이 안전하다.
nullable | null 값의 허용 여부를 설정하며, false로 설정하면 DDL 생성 시에 not null 제약조건이 붙는다. (기본값은 true) |
unique | @Table의 uniqueConstraints와 같지만 한 컬럼에 간단한 유니크 제약조건을 걸 때 사용한다. |
columnDefinition | 데이터베이스 컬럼 정보를 직접 지정할 때 사용한다. |
length | 문자 길이 제약조건을 지정하며, String 타입에만 사용할 수 있다. |
precision, scale | BigDecimal, BigInt 타입에서 사용하며 precision은 소수점을 포함한 전체 자리수를, scale은 소수의 자리수를 의미한다. |
@Enumerated
- 자바의 enum 타입을 매핑할 때 사용한다.
- @Enumerated 어노테이션의 value 속성의 기본값은 ORDINAL로, enum에 정의된 순서대로 숫자값이 데이터베이스에 저장된다.
- 만약 enum 순서가 바뀌거나 추가되면 데이터베이스에 저장된 enum의 순서는 바뀌지 않기 때문에, ORDINAL보다 STRING으로 저장하는 것이 안전하다.
'Spring > JPA' 카테고리의 다른 글
JPA와 컬렉션 (0) | 2022.03.25 |
---|---|
프록시와 연관관계 관리 (0) | 2022.03.25 |
스프링에서의 영속성 관리 (0) | 2022.03.05 |
영속성 컨텍스트와 연속성 관리 (0) | 2022.03.05 |
N+1 문제와 해결 방법 (0) | 2022.03.05 |