1. 객체와 테이블 매핑
@Entity
- JPA 가 관리하는 객체이며, 데이터베이스 테이블과 매핑해서 사용한다.
- 기본 생성자 필수 (public / protected)
- final 클래스, enum, interface, inner 클래스 사용은 안된다.
- 저장할 필드에 final 사용은 안된다.
- 속성
- name
- JPA에서 사용할 엔티티 이름
- default 는 객체 명
- name
@Table
- 속성
- name
- 데이터베이스 테이블에 대한 이름을 지정한다.
- uniqueConstraints
- 유니크 제약조건을 부여한다.
- name
2. 데이터베이스 스키마 자동 생성
옵션
- hibernate.hbm2ddl.auto
- create : 시작 시점에 drop
- create-drop : 종료 시점에 drop
- update : 변경 부분만 반영 (컬럼을 추가하는 것만 가능하다.)
- validate : 엔터티와 테이블이 정상적으로 매핑되었는지 확인 시켜준다.
- 운영 장비에는 절대로 create / create-drop / update 를 사용하면 안된다.
3. 필드와 컬럼 매핑
매핑 어노테이션 정리
어노테이션 | 설명 |
@Column | 컬럼 매핑 |
@Temporal | 날짜 타입 매핑 |
@Enumerated | enum 타입 매핑 |
@Lob | CLOB, BLOB 매핑 |
@Transient | 특정 컬럼은 매핑하고 싶지 않다. (메모리에서만 사용할 것이다.) |
@Column
속성 | 설명 | 기본값 |
name | 필드와 매핑할 테이블에서의 컬럼명 | 객체의 필드이름과 동일하다. |
insertable updatable |
컬럼을 수정했을 때, 데이터베이스에 변경 사항을 반항 할 것인가 | TRUE |
nullable(DDL) | null 값의 허용 여부를 설정한다. false 로 설정하면 not null 제약조건이 붙는다. |
|
unique(DDL) | 잘 쓰지 않는다. (유니크 제약 조건의 이름이 랜덤값으로 들어가기 때문이다.) @Table(uniqueConstraints = ...) 으로 이름을 줘서 사용하는 방법을 더 많이 사용한다. |
|
columnDefinition | 데이터베이스 컬럼 정보를 직접 줄 수 있다. ex) columnDefinition = "char(1)" |
|
length | 문자 길이의 제약조건을 줄 수 있다. 오직 String 타입에서만 사용한다. |
|
precision, scale(DDL) |
BigDecimal 타입에서 사용한다. (BigInteger도 가능) precision : 소수점을 포함한 전체 자리수 scale : 소수의 자리수 |
precision=19, scale=2 |
@Enumerated
속성 | 설명 | 기본값 |
value | EnumType.ORDINAL : enum 순서를 데이터베이스에 저장 EnumType.STRING : enum 이름을 데이터베이스에 저장 |
EnumType.ORDINAL |
@Temporal
- hibernate 최신에서는 LocalDate / LocalDateTime 을 사용하고, @Temporal을 사용할 필요가 없다.
속성 | 설명 | 기본값 |
value | - TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑 ex) [2020-01-01] - TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑 ex) [12:12:12] - TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑 ex) [2020-01-01 12:12:12] |
@Lob
- 옵션은 없다.
- String 이면 CLOB
- 나머지는 BLOB 으로 매핑된다.
@Transient
- 매핑을 하기 싫은 프로퍼티에 사용한다.
4. 기본키 매핑
기본키 직접 할당 : @Id 만 사용
자동 기본키 할당 : @Id + @GeneratedValue
@GeneratedValue 옵션 (strategy)
옵션 | 설명 |
AUTO | Dialect 에 따라서 아래의 옵션 중 알맞은 것을 자동으로 설정해준다. |
IDENTITY | 기본 키 생성을 데이터베이스에 위임한다. - MySQL : auto_increment |
SEQUENCE | 데이터베이스 시퀀스 오브젝트를 통해서 id 값을 세팅해준다. Hibernate: call next value for hibernate_sequence (기본 시퀀스) @SequenceGenerator을 통해서 시퀀스를 생성할 수 있다. |
TABLE | 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다. 장점 - 모든 데이터베이스에서 사용 가능하다. 단점 - 성능 |
권장하는 식별자 전략
- 기본 키 제약 조건
- null 이면 안된다.
- 유일해야 한다.
- 변하면 안된다.
- 미래를 예측할 수 없으므로
- Long형 + 대체키 [비즈니스와 전혀 상관없는 키 ex) auto_increment, sequence, uuid] + 키 생성전략
IDENTITY 전략
- @Id 에 값을 넣으면 안된다.
- 데이터베이스에 쿼리를 날리면, Null 로 들어가게 되며, 그때 돼서야 db에서 값을 설정한다.
반드시 알아야 할 유의점!!
- 아직 데이터베이스에 넣기 전에, 1차 캐시의 PK 값이 없으므로 1차 캐시를 세팅할 방법이 없다.
- 따라서, IDENTITY 전략은 em.persist를 하면, 그 순간 insert query를 날리게 된다.
- (예전에 봤던, 지연 로딩을 통해서 트랜잭션을 커밋하는 시점에 날리지 않고, 바로 SQL을 날리게 된다.)
- em.persist 이후, id 값을 출력하는 로직이 있다면, select 쿼리는 날리지 않는다.
- DB 내부적으로, insert 를 하면 id 값을 리턴하는 것을 JPA 에서 사용할 수 있도록 지원하기 때문이다.
SEQUENCE 전략
- em.persist 를 하는 과정에서
- call next value for MEMBER_SEQ 를 통해서, 데이터베이스 시퀀스 테이블에서 Id 값을 가져온다.
- 이후 1차 캐시에 Id 와 엔터티를 저장한다.
- IDENTITY 와 다르게 버퍼링이 가능하다.
@Entity
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ",
initialValue = 1, allocationSize = 1
)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
...
}
create sequence MEMBER_SEQ start with 1 increment by 1
그렇다면, 자꾸 시퀀스 테이블에 가는 것은 안좋다.
- 미리 데이터베이스에서 allocationSize 만큼 당겨놓고, 메모리에서 한개씩 쓴다.
- 여러 요청에도 동시성 이슈없이 수행된다.
- allocationSize 수정을 통해서, DB 네트워크를 타는 횟수를 줄인다.
- 50 이나, 100 정도가 적당하다.
TABLE 전략
@Entity
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR",
table = "MY_SEQUENCES",
pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
}
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key (sequence_name)
)
시퀀스 전용 테이블이 생성되어있고, 다음 키 값 (next_val) 은 뭐가 되어야하는지 들어있다.
시퀀스 전략과 마찬가지로, allocationSize 수정을 통해서, DB 네트워크를 타는 횟수를 줄인다.
'강의 정리 > 자바 ORM 표준 JPA' 카테고리의 다른 글
6. 고급 매핑 (0) | 2020.12.29 |
---|---|
5. 다양한 연관관계 매핑 (0) | 2020.12.28 |
4. 연관관계 매핑 기초 (0) | 2020.12.27 |
2. 영속성 관리 (0) | 2020.12.26 |
1. JPA 시작하기 (0) | 2020.12.26 |