4장 - 엔티티 매핑
1. @Entity
- 테이블과 매핑할 클래스는
@Entity
어노테이션을 필수로 붙여야 한다. name
: 엔티티의 이름, 보통 기본값인 클래스 이름을 사용한다.- 기본 생성자는 필수
- final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
- 저장할 필드에 final을 사용하면 안 된다.
2. @Table
@Table
은 엔티티와 매핑할 테이블을 지정한다.- 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용
속성
name
: 매핑할 테이블 이름catalog
: catalog 기능이 있는 데이터베이스에서 catalog 매핑schema
: schema 기능이 있는 데이터베이스에서 schema 매핑uniqueConstraints
: DDL 생성 시 유니크 제약조건을 만듦
3. 데이터베이스 스키마 자동 생성
- JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원한다.
application.yml
spring:
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
show-sql: true // 테이블 생성 DDL 출력 가능
hibernate.ddl-auto 속성
create
: 기존 테이블을 삭제하고 새로 생성한다 (DROP + CREATE)create-drop
: create 속성에 추가로 어플리케이션을 종료할 때 생성한 DDL을 제거한다.(DROP + CREATE + DROP)update
: DB테이블과 엔티티 매핑 정보를 비교해서 변경사항만 수정한다validate
: DB테이블과 엔티티 매핑 정보를 비교해서 차이가 있으면 경고를 남기고 어플리케이션을 실행하지 않는다.none
: 자동 생성 기능을 사용하지 않음(유효하지 않은 옵션 값)
주의사항
- 운영서버에서 create, create-drop, update처럼 DDL을 수정하는 옵션은 절대 사용하면 안 된다. 오직 개발 서버나 개발 단계에서만 사용해야 한다.
4. DDL 생성 기능
@Entity
@Table(name="MEMBER")
public class Member {
@Id
@Column(name="ID")
private String id;
@Column(name = "NAME", nullable = false, length = 10)
private String username;
...
}
@Column
매핑 정보의 속성 값 지정
nullable
: false로 지정하면 자동 생성되는 DDL에 not null 제약 조건을 추가할 수 있다.length
: 문자 크기 지정
다양한 제약 조건을 추가할 수 있지만 이런 기능들은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.
5. 기본 키 매핑
JPA가 제공하는 데이터베이스 기본 키 생성 전략
- 직접 할당 : 기본 키를 애플리케이션에 직접 할당
- 자동 생성 : 대리 키 사용 방식
- IDENTITY : 기본 키 생성을 데이터베이스에 위임한다.
- SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당한다.
- TABLE : 키 생성 테이블을 사용한다.
5.1 기본 키 직접 할당
@Id
로 매핑em.persist()
로 엔티티를 저장하기 전에 애플리케이션에서 기본 키를 직접 할당하는 방식
5.2 IDENTITY 전략
기본 키 생성을 데이터베이스에 위임하는 전략
- 데이터베이스에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 때 사용
@Id
와@GenerateValue
어노테이션을 함께 사용@GenerateValue
의 strategy 속성 값을GenerationType.IDENTITY
로 지정
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
}
- IDENTITY 전략은 ****JPA는 기본 키 값을 얻어오기 위해 데이터베이스를 추가로 조회한다.
- 식별자를 구하기 위해
em.persist()
를 호출하는 즉시 INSERT SQL이 데이터베이스에 전달되므로, 이 전략은 트랜잭션을 지원하는 쓰기 지연이 동작하지 않는다.
5.3 SEQUENCE 전략
데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오프젝트이고, SEQUENCE 전략은 이 시퀀스를 사용해서 기본 키를 생성한다.
- 시퀀스 생성
@SequenceGenerator
: 시퀀스 생성기 등록@GenerateValue
의 strategy 속성 값GenerationType.SEQUENCE
로 지정generator
: 등록한 시퀀스 생성기 선택
CREATE TABLE BOARD (
ID BIGINT NOT NULL PRIMARY KEY,
DATA VARCHAR (255)
)
// 시퀀스 생성
CREATE SEQUENCE BOARD_SEQ START WITH 1 INCREMENT BY 1;
// 시퀀스 매핑
@Entity
@SequenceGenerator (
name = "BOARD_SEQ_GRNERATOR",
sequenceName = "BOARD_SEQ", // 매핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BOARD_SEQ_GENERATOR")
private Long id;
...
}
IDENTITY 전략과의 차이
- SEQUENCE 전략
em.persist()
를 호출할 때 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회- 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장
- 트랜잭션을 커밋해서 플러시가 일어나면 엔티티를 데이터베이스에 저장
- IDENTITY 전략
- 먼저 엔티티를 데이터베이스에 저장한 후에 식별자를 조회해서 엔티티의 식별자를 할당
@SequenceGenerator 속성
속성 | 기능 | 기본값 |
---|---|---|
name | 식별자 생성기 이름 | 필수 |
sequenceName | 데이터베이스에 등록되어 있는 시퀀스 이름 | hibernate_sequence |
initialValue | DDL 생성 시에만 사용, 시퀀스 DDL을 생성할 때 처음 시작하는 수 지정 | 1 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수 | 50 |
catalog, schema | 데이터베이스 catalog, schema 이름 |
5.4 Table 전략
키 생성 전용 테이블을 하나 만들고, 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내 내는 전략
- 키 생성 용도로 사용할 테이블 생성
- 시퀀스 이름 : sequence_name
- 시퀀스 값 : next_val
@TableGenerator
: 테이블 키 생성기 등록@GenerateValue
의 strategy 속성 값GenerationType.TABLE
로 지정- SEQUENCE 전략과 내부 동작 방식이 같다
create TABLE MY_SEQUENCES ( // 키 생성 용도
sequence_name varchar (255) not null,
next_val bigint,
primary key (sequence_name)
)
// 테이블 전략 매핑
@Entity
@TableGenerator(
name = "BOARD_SEQ_GENERATOR",
table = "MY_SEQUENCES",
pkColumnValue = "BOARD_SEQ", allocationSize = 1)
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "BOARD_SEQ_GENERATOR")
private Long id;
...
}
@TableGenerator 속성
name | 식별자 생성기 이름 | 필수 |
---|---|---|
table | 키 생성 테이블명 | hibernate_sequences |
pkColumnName | 시퀀스 컬럼명 | sequence_name |
valueColumnName | 시퀀스 값 컬럼명 | next_val |
pkColumnValue | 키로 사용할 값 이름 | 엔티티 이름 |
initialValue | 초기 값. | 0 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수 | 50 |
catalog, schema | 데이터베이스 catalog, schema 이름 | |
uniqueConstraints(DDL) | 유니크 제약 조건을 지정 |
5.5 Auto 전략
@GenerateValue
의 strategy 속성 값GenerationType.AUTO
로 지정- 선택한 데이터베이스 방언에 따라 전략을 자동으로 선택
- 데이터베이스를 변경해도 코드를 수정할 필요가 없고, 키 생성 전략이 아직 확정되지 않은 개발 초기 단계나 프로토타입 개발 시 편리하게 사용 가능하다.
- 시퀀스나 테이블 전략이 선택되면 시퀀스나 키 생성용 테이블을 미리 만들어두어야 한다.
6. 필드와 컬럼 매핑 : 레퍼런스
6.1 @Column
- 객체 필드를 테이블 컬럼에 매핑할 때 사용
속성 | 기능 | 기본 값 |
---|---|---|
name | 필드와 매핑할 테이블의 컬럼 이름 | 객체의 필드 이름 |
nullable | null 값의 허용 여부를 설정. false로 설정하면 DDL 생성 시에 not null 제약 조건이 붙음 | true |
unique | 한 컬럼에 간단히 유니크 제약 조건을 걸 때 사용 (@Table의 uniqueConstraints와 같음) | |
columnDefinition | 데이터베이스 컬럼 정보를 직접 줄 수 있다. | 필드의 자바 타입과 방언 정보를 사용해서 적절한 컬럼 타입을 생성 |
length | 문자 길이 제약 조건, String 타입에만 사용 | 255 |
precision, scale | BigDecimal 타입 혹은 BigInteger 타입에서 사용. precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수. ( double, float 타입에는 적용되지 않음) | precision = 19, scale = 2 |
6.2 @Enumerated
- 자바의 enum 타입을 매핑할 때 사용
value
- EnumType.ORDINAL : enum 순서를 데이터베이스에 저장
- EnumType.STRING : enum 이름을 데이터베이스에 저장
6.3 @Temporal
- 날짜 타입을 매핑할 때 사용
value
- TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑
- TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑
6.4 @Lob
- 데이터베이스 CLOB, BLOB 타입과 매핑
- 지정할 수 있는 속성이 없다.
- 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB으로 매핑한다.
6.6 @Transient
- 이 필드는 매핑하지 않는다
- 객체에 임시로 어떤 값을 보관하고 싶을 때 사용한다.
6.7 @Access
- JPA가 엔티티에 접근하는 방식을 지정한다.
- 필드 접근 : AccessType.FIELD
- 프로퍼티 접근 : AccessType.PROPERTY
- 지정하지 않으면 @Id의 위치를 기준으로 접근 방식이 설정됨
'자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] 7장 - 고급 매핑 (0) | 2023.06.12 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 6장 - 다양한 연관관계 매핑 (0) | 2023.05.15 |
[자바 ORM 표준 JPA 프로그래밍] 5장 - 연관관계 매핑 기초 (0) | 2023.05.01 |
[자바 ORM 표준 JPA 프로그래밍] 3장 - 영속성 관리 (0) | 2023.04.24 |
[자바 ORM 표준 JPA 프로그래밍] 1장 - JPA 소개 (0) | 2023.04.24 |