JPA의 핵심 - 영속성 컨텍스트나 내부 매커니즘 / 객체와 관계형 데이터베이스를 어떻게 매핑하는지
✍엔티티 매핑
ㆍ객체와 테이블 매핑
- 객체 & 테이블 매핑 - @Entity @Table
- 필드와 컬럼 매핑 - @Column
- 기본 키 매핑 - @Id
- 연관관계 매핑 - @ManyToOne @JoinColumn
@Entity
- @Entity가 붙은 클래스는 JPA가 전담하여 관리.
- 기본 생성자 필수
- final 클래스, enum, interface, inner 클래스 X
- 저장할 필드에 final 사용 X
@Table
- name = 매핑할 테이블 이름
- uniqueConstraints = unique 제약조건을 걺
ㆍ데이터베이스 스키마 자동 생성
애플리케이션 로딩 시점에 자동으로 테이블을 생성 할 수 있다.
데이터 베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL(Data Definition Language - 데이터 정의어) 생성.
<property name="hibernate.hbm2ddl.auto" value="create" />
persistence.xml 파일에 다음과 같은 속성을 추가하면 애플리케이션 로딩 시점에 Entity와 매핑된 기존 테이블들을 지우고, 다시 생성한다.
=> 운영단계에서는 사용 X, 개발 단계에서 생산성을 위해 사용.
value
- create : 기존 테이블 삭제 -> 다시 생성
- create-drop : create와 동일 + 종료 시점에 테이블 DROP
- update : 변경분만 반영(운영에서 사용 X) -
- validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
- none : 사용 X
- 데이터베이스 방언별로 스키마가 달라짐.
- create, create-drop, update 절대절대절대절대 운영 장비에 사용하면 안된다.
=> 개발서버나 staging, 운영 서버에서는 가급적 사용 하지 않는다.
ㆍ필드와 컬럼 매핑
- 어플리케이션에 영향을 끼치지 않음(RunTime에 영향 X). DDL을 생성하는 데에만 영향을 줌. => DDL 생성 기능
@Column - 컬럼 매핑 - Entity 필드를 구성할 때, 제약 조건들을 넣는 것이 테이블을 보지 않아도 알 수 있어, 편하다.
- name = Entity 클래스 변수명과 DB 컬럼명이 다를 때, 데이터베이스 컬럼 명을 적어줌.
- unique = 유니크 제약조건을 걸 때 (boolean) - 제약조건이 랜덤값이라 운영에서는 잘 사용하지 않음.
- length = 길이 제한
- insertable, updatable = 필드의 등록, 변경 가능 여부 (boolean)
- nullable = false로 지정 시 -> not null
- columnDefinition(DDL) = 컬럼 정보를 직접 줄 수 있다.
- precision, scale(DDL) = BigDecimal, BigInteger같은 큰 숫자를 다룰 때 사용.
@Enumerated
- Entity에서 Enum 타입을 매핑할 때 사용.
- EnumType.ORDINAL = Enum 데이터의 순서를(ordinal) DB에 저장. (권장되지 않음)
- EnumType.STRING = Enum의 상수 문자 그대로 DB에 저장.
@Temporal
- Date 타입을 사용할 때 사용.
- LocalDate, LocalDateTime 사용할 때는 생략 가능.(알아서 date나 timestamp로 변경해준다.)
-> TemporalType.DATE : 날짜 / TemporalType.TIME : 시간 / TemporalType.TIMESTAMP : 날짜&시간
@Lob
- Varchar을 넘어서는 큰 데이터를 사용할 때 사용. 문자타입은 기본적으로 'clob'으로 생성, 나머지는 'blob'
@Transient
- 특정 필드를 DB 컬럼에서 제외할 때.
ㆍ기본 키 매핑
auto-increment = 값을 넣어주지 않아도, 값을 순차적으로 증가시키면서 자동으로 할당.
@Id - 직접 할당.
@GeneratedValue - 자동 할당.
Id 값을 세팅해주지 않아도 자동으로 할당됨.
- 전략 -
- strategy = GenerationType.AUTO >> DB 방언에 맞춰서 자동 생성.
- strategy = GenerationType.IDENTITY >> 기본 키 생성을 데이터베이스에 위임. (DB별로 자동생성 전략이 다름)
- strategy = GenerationType.SEQUENCE >> sequence 오브젝트 통해 값을 가져오고, 세팅. (필드값을 정수형으로 바꿔주자. Long 형 권장) / 직접 Sequence를 지정할 수도 있음 Entity에 @SequenceGenerator 을 사용하여 세팅.
- strategy = GenerationType.TABLE >> 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략. Entity에 @TableGenerator을 사용하면 따로 Table을 생성할 수 있다.
IDENTITY 전략은 DB에 값을 넣을 때까지 키 값을 알 수 없다. JPA 동작 방식에서 Transaction.commit()이 이루어져야 실제 쿼리가 DB에 날라가는데, 따라서 commit하기 전까지 해당 데이터를 참조할 수 없는 상황이 발생한다.
=> 이와 같은 문제를 방지하기 위해 IDENTITY 전략은 Entity를 영속성 컨테이너에 저장할 때, 바로 INSERT 쿼리를 날려버린다.
SEQUENCE 전략에서는 영속성 컨텍스트에 Entity를 넣을 때, Id가 필요하기 때문에 시퀀스를 DB에서 불러와서 Id 값을 할당한다. (INSERT 쿼리를 보내는 것이 아님) 따라서, Sequence 전략은 버퍼링이 가능.
성능 최적화 옵션 allocationSize = 시퀀스 한 번 호출에 증가하는 수. 해당 단위가 될 때까지 매번 DB에 increment하는 것이 아닌, Memory에서 갖다 씀. (50이나 100정도가 적정)
권장 식별자 전략
ㆍ기본 키 제약 조건 = not Null, 유일, 변하면 안된다.
ㆍ비지니스를 키로 사용하지 말자.
ㆍ권장 = Long형 + 대체키 + 키 생성 전략 사용
- h2 Database 파일 추가 - jdbc:h2:~/"DB명"
- spring Boot 의 기본 설정은 Java의 캐멀케이스를 자동으로 '소문자 + _' 조합으로 변환해준다.
본 게시글은 Inflearn 강의를 토대로 제작되었습니다.
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런
www.inflearn.com