티스토리 뷰
목차
1. 객체 테이블 매핑
2. 데이터베이스 스키마 자동생성
3. 필드와 컬럼 매핑
4. 기본키 매핑
1. 객체 테이블 매핑
1) @Entity
클래스와 테이블을 매핑
기본 생성자 필요(jpa 내부적으로 사용)
테이블명은 기본적으로 클래스명과 동일하게 생성
추가 설정은 @Table의 속성 참고
2. 데이터베이스 스키마 자동생성
애플리케이션 로딩 시점에 DB 방언에 맞는 DDL실행(개발초기에서만 사용)
DB 방언 : hibernate.dialect 옵션 (mysql, oracle 등)
자동생성 : hibernate.hbm2ddl.auto 옵션 (create, create-drop, update, validate, none)
- 개발초기 : create, update
- 테스트 : update, validate
- 스테이징과 운영 : none, validate
로컬에서만 자유롭게 사용하고 다른 서버는 직접 DDL스크립트를 만들어 사용하자.
update - 컬럼 삭제는 반영되지 않음
3. 필드와 컬럼 매핑
1) @Column
> name : DB 컬럼명 지정
> length : 문자길이 제약조건
> insertable : false 면 저장시 insert 쿼리에서 제외(읽기 전용)
> updatable : false 면 컬럼이 변경되어도 update 쿼리에서 제외
> nullable : false 면 not null 제약조건
> unique : unique 제약조건 (제약조건 이름이 랜덤 생성)
- @Table의 uniqueConstraints 사용 : 제약조건 이름지정
> columnDefinition : DDL 직접 적용
@Column(columnDefinition = "varchar(100) defalult 'empty'")
private String name;
2) @Enumerated
EnumType.ORDINAL : enum 순서를 저장(Integer)
EnumType.STRING : enum 이름을 저장(varchar)
순서는 변경될 가능성이 있기 때문에 STRING을 사용하자
3) @Temporal
TemporalType : DATE, TIME, TIMESTAMP
@Temporal(TemporalType.TIMESTAMP)
private Date createDate;
// java 8
private LocalDate createDate; // date
private LocalDateTime createDate; // timestamp
4) @Lob : varchar 보다 큰 문자열
문자타입 : clob
나머지 : blob
5) @Transient
컬럼 매핑에서 제외
4. 기본키 매핑
1) @ID : 직접할당
member.setId(1L);
2) @GeneratedValue : 자동생성
> TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용
- @TableGenerator 필요
- 성능상의 단점
> AUTO : 방언에 따라 자동 지정, 기본값
- H2로 테스트한 결과 SEQUENCE 속성과 동일
> IDENTITY : 데이터베이스에 위임 (예, MYSQL의 auto_increment)
- 트랜잭션 커밋 시점에 insert 쿼리를 실행하기 때문에 PK는 트랜잭션 커밋이 되어야 알 수 있다
- 이를 해결하기 위해 예외적으로 IDENTITY 속성의 경우 persist() 호출 시점에 insert 쿼리를 실행한다.
- persist() 호출 시점에 insert 쿼리 실행
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
// ...
// insert sql 실행
em.persist(member);
> SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
- @SequenceGenerator 필요
- persist() 호출 시점에 sequence를 조회(쿼리실행 H2 : call next value for hibernate_sequence)해 해당 엔티티를 영속화
- 트랜잭션 커밋 시점에 insert 쿼리 실행
@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;
// ...
}
- persist() 호출 시점에 시퀀스 값을 가져온다 ( call next value for sequence_name )
- id 컬럼에 값 저장 후 영속화
- 트랜잭션 커밋 시점에 insert 쿼리 실행
- 성능 최적화
allocationSize = 50으로 설정
1) call next value DB SEQ와 메모리의 현재값을 1로 설정
2) call next value DB SEQ의 현재값을 51로 설정
3) 메모리에서 51까지 사용
4) call next value DB SEQ의 현재값을 101로 설정
DB SEQ | MEMORY |
1 | 1 |
51 | 1 |
51 | 2 |
51 | 3 ~ 50 |
101 | 51 |
동시성 이슈는 발생하지 않음.
1번 서버에서 호출
DB SEQ : 51
MEMORY : 1 ~ 50 사용
2번 서버에서 호출
DB SEQ : 101
MEMORY : 51 ~ 100 사용
숫자는 정확하지 않음.
> 비지니스 데이터를 키로 사용하지 말자.
> DB 키 생성전략을 사용하자.
출처
https://www.inflearn.com/course/ORM-JPA-Basic 자바 ORM 표준 JPA 프로그래밍 - 기본편(김영한)
'ORM > JPA' 카테고리의 다른 글
[JPA] 6. 프록시와 연관관계 관리 (0) | 2021.12.14 |
---|---|
[JPA] 5. 고급 매핑 (0) | 2021.12.01 |
[JPA] 4. 다양한 연관관계 매핑 (0) | 2021.11.29 |
[JPA] 3. 연관관계 매핑 (0) | 2021.11.09 |
[JPA] 1. 내부동작방식 (0) | 2021.11.06 |
- Total
- Today
- Yesterday
- Git
- MySQL
- 클린코드
- Stream
- 도메인 모델링
- 스프링 카프카 컨슈머
- 마이크로서비스 패턴
- 스프링 예외 추상화
- 육각형 아키텍처
- Spring
- HTTP 헤더
- mockito
- kafka
- 계층형 아키텍처
- TDD
- named query
- JPA
- http
- 트랜잭셔널 아웃박스 패턴
- H2
- spring rest docs
- 이벤트 스토밍
- Spring Boot
- Spring Data JPA
- ATDD
- clean code
- java8
- 폴링 발행기 패턴
- 학습 테스트
- Ubiquitous Language
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |