@Entity가 붙은 클래스는 JPA가 관리, Entity라 한다.
@Table은 Entity와 매핑할 DB 테이블을 설정한다.
@Entity가 붙는 클래스는 기본 생성자가 필수다.
🤔 이유는 추측건대, 일반적으로 컴파일러가 기본 생성자를 만들어 주지 않는 상황엔 인스턴스를 생성도 못 하는 경우가 생기기 때문에 기본 생성자 코드를 작성하는게 일반적인 관례라서 그렇지 않을까싶다.
설정된 Entity는 애플리케이션 실행시점에 적절한 방언(타입)으로 DDL을 자동으로 생성한다. 생성된 DDL은 운영 서버에는 적합하지 않아 테스트용도로 사용한다.
@Table에서 Unique 제약 조건을 걸 수 있다.
@Column : 컬럼과 관련된 설정 매핑
@Enumerated : enum 타입을 매핑
@Temporal : DB 날짜 타입에 매핑
@Lob : DB BLOB, CLOB(default)에 매핑
@Transient : 특정 필드를 컬럼에 매핑시키지 않음
@Column
name : 필드와 매핑할 테이블의 컬럼 이름을 설정할 수 있다.
insertable, updatable : DB에 등록, 변경 가능 여부를 설정할 수 있다.
nullable : null 값의 허용 여부를 설정.(DB not null 제약조건)
length : 문자 길이 제약조건을 설정할 수 있다.(String 한정 varchar로 매핑되기 때문)
🤔 가급적 length는 쓰는 게 좋다. 실제 DB 구조를 보지 않아도 정보를 얻을 수 있기 때문
@Enumerated
default는 ORDINAL 타입이며 enum 순서(integer)를 데이터베이스에 저장한다.
--> 필드 순서에따라 DB에 저장되는 값이 달라지므로 위험성이 크다.
STRING 타입은 enum의 이름(varchar)을 데이터베이스에 저장한다.
@Temporal
자바 8부터 LocalDate, LocalDateTime이 있어서 최근엔 어노테이션을 안 쓴다.
@Id : 내가 이 필드를 기본키로 설정하겠다. (직접 할당)
@GeneratedValue : 기본 키 값이 자동으로 생성된다.
@GeneratedValue
@Id
@GeneratedValue(strategy = GenearationType.~)
IDENTITY : 데이터베이스에 위임(MySQL)
JPA는 영속성 컨텍스트에 Entity를 넣는 시점에 PK가 null이 되서는 안 되기 때문에
MySQL의 AUTO_INCREMENT 전략에 맞춰 INSERT 쿼리를 이 시점에 날린다.
SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용(@SequenceGenerator, Oracle)
initialValue = 1, allocationSize = 100이라고 가정하면
초기 영속성 컨텍스트에 Entity를 넣는 시점에 DB nextCall 호출 -> 1
DB는 allocationSize를 맞추기 위해 한 번 더 호출 -> 101
어플리케이션은 Id 값이 1 -> 2 -> 3으로 진행되기 때문에 DB 시퀀스 값에 도달하기 전까지
nextCall을 호출하지 않는다. (최적화)
TABLE : 키 생성용 테이블 사용(@TableGenerator, 모든 DB, But 성능 👎)
AUTO : 방언에 따라 타입 자동 지정(default)
🤔 현재는 @GeneratedValue가 붙는 필드의 타입은 Long을 사용을 권장한다 Integer(10억)를 쓰다가 Long으로 바꾸는 것이 비용 손해가 큰 것으로 보인다.