티스토리 뷰
@Entity
- @Entity가 클래스단에 붙은 클래스는 JPA가 관리하는 Entity라고 지정할 수 있다.
- JPA에서는 entity를 리플렉션으로 관리하기 때문에 항상 기본 생성자가 필수이다. 접근 제어자의 경우
public
과protected
까지만 허용되며 보통은protected
를 많이 쓰는 추세이다. - final 클래스, enum 클래스, interface, inner 클래스 모두에 사용이 불가능 하며 필드에는 final 상수로 지정하면 안된다.
property
- name
- JPA에서 사용할 entity의 이름을 지정할 수 있다.
- default: class name
- 가급적 default값을 사용하도록 하자. 동일한 네이밍의 entity 클래스를 사용할 경우에만 건드는 것을 추천.
@Table
- entity와 매핑할 테이블을 직접 지정해줄 수 있다.
property
- name
- 매핑할 테이블 이름
- default: entity name (
@Entity
의 name을 지정하지 않았으면 물론 클래스 네임을 따라간다.)
- catalog
- 데이터베이스 catalog 매핑
- schema
- 데이터베이스 schema 매핑
- uniqueConstraints(DDL option)
- DDL 생성 시에 유니크 제약 조건 생성용
데이터베이스 스키마 자동 생성
jpa는 존재하지 않은 스키마에 대해서 @Entity
가 걸려있는 클래스의 정보를 가지고 자동으로 스키마를 생성해주기도 한다. DDL을 어플리케이션 시점에서 자동으로 생성해주며 데이터베이스별 방언이 달라도 각 데이터 베이스에 맞는 적절한 DDL을 생성해준다.
예시)
<property name="hibernate.hbm2ddl.auto" value="create" />
물론 이런 자동 생성 기능은 개발 시에서만 사용을 해야하며 실제 운영 서버의 경우 아예 옵션을 끄거나 적당히 테이블을 다듬어서 사용해야 한다.
옵션 | 설명 |
---|---|
create | 기존 테이블 삭제 후 다시 생성 (drop + create) |
create-drop | create와 같지만 종료시점에 테이블을 drop (drop + create + drop) |
update | 변경분만 반영 |
validate | 엔티티와 테이블이 정상 매핑되었는지만 확인 |
none | 자동 생성 사용하지 않음 |
앞서 이야기한 대로 운영 서버에는 절대로 create, create-drop, update를 사용하면 안되기 때문에 항상 유의해아한다. 이들은 개발 초기단계에서만 사용되어야 하며 운영서버는 항상 none을 사용하도록 하자.
- 개발 초기 단계 : create, update
- CI 서버 또는 초기화 상태로 자동화된 테스트를 진행하는 개발자 서버 : create, create-drop
- 테스트 서버 : update, validate
- 운영 서버 : validate, none
아래에 설명할 @Column
등과 같은 매핑어노테이션에서 제약조건을 추가할 수 있지만 말했다시피 DDL 생성기능 자체는 DDL을 자동 생성할 경우에만 사용되고 이후 JPA 실행 로직에는 영향을 주지 않으니 사용하지 않은 옵션은 제거하도록 하자!
매핑 어노테이션
어노테이션 | 설명 |
---|---|
@Column | 컬럼 매핑 |
@Temporal | 날짜 타입 매핑 |
@Enumerated | enum 타입 매핑 |
@Lob | BLOB, CLOB 매핑 |
@Transient | 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)2 |
@Column
필드 값들에 컬럼을 매핑하는데 주로 사용된다. 대부분의 필드 값들이 다 해당 어노테이션에 포함된다고 보면 된다.
속성 | 설명 | 기본값 |
---|---|---|
name | 필드와 매핑할 테이블의 컬럼 이름 | 객체의 필드 이름 |
insertable, updatable | 등록, 변경 가능 여부 | TRUE |
nullable(DDL) | null 값 허용 여부 설정 | |
unique(DDL) | 유니트 제약 조건 설정 | |
columnDefinition(DDL) | 직접 컬럼에 정보 입력 | |
length(DDL) | 문자 길이 제약 조건, String type에만 사용 | 255 |
percision, scale(DDL) | BigDecimal 타입에서 소수점 포함한 전체 자리(percision), 소수 자리수(scale)을 설정 | percision=19, scale=2 |
나머지는 사실 DDL 생성조건이기 때문에 넘어가고, insertable과 updatable을 조금 유의하면서 사용한다면 좋을 것 같다.
- insertable : false 사용 시 데이터베이스에 저장되지 않음, 읽기전용 필드로 변환
- updatable : false 사용 시 데이터베이스에 수정되지 않음
@Temporal
날짜 Date
혹은 Calendar
를 사용할 경우 이를 테이블과 매핑할 때 사용한다.
요즘은 대부분 LocalDate
나 LocalDateTime
을 사용하기 떄문에 이를 사용한다며 생략해도 된다.
@Enumerated
자바의 enum 타입을 매핑할 때 사용한다.
두가지 옵션이 존재하는데,
속성 | 설명 | 기본값 |
---|---|---|
value | ÈnumType.ORIDINAL : enum 순서를 데이터베이스에 저장EnumType.STRING : enum 이름을 데이터베이스에 저장 |
EnumType.ORDINAL |
말 그대로 ORIDINAL
은 enum의 순서를 데이터베이스에 저장하는 옵션이다.
public enum Role {
USER, ADMIN
}
다음과 같은 enum 클래스가 있을 때 각각 USER과 ADMIN이지만 이 둘의 순서는 0번째, 1번째 이기 때문에 해당 옵션을 사용했을 경우 실제 DB에는 0과 1로 저장이 된다.
따라서 항상 enum의 목적은 순서가 아닌 그 네이밍이 필요하기 때문에 EnumType.STRING
을 잊지말고 사용해주어야 한다.
@Lob
데이터베이스의 BLOB과 CLOB 타입에 매핑하기 위해서 사용된다. varchar를 뛰어넘는 저장 타입
지정할 수 있는 속성은 따로 없으며 필드 타입이 문자면 CLOB, 나머지는 BLOB으로 자동 매핑 된다.
- CLOB : String, char[], java.sql.CLOB
- BLOB : byte[], java.sql.BLOB
@Transient
데이터베이스와 매핑하지 않고 순수 필드로써만 사용하고 싶을 경우 해당 어노테이션을 사용한다.
@Transient
private String tmp;
기본 키 매핑
기본키 매핑을 하기 위한 어노테이션은 딱 두가지만 존재한다.
- @Id
- @GeneratedValue
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
모든 entity에는 @Id
어노테이션이 달린 기본키가 존재해야하고, 자동 생성을 설정할 때 @GeneratedValue
어노테이션을 사용한다.
IDENTITY strategy
- 기본키 생성을 데이터베이스에 위임
- 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용한다 (ex AUTO_INCREMENT)
- AUTO_INCREMENT되기 때문에 db에 저장하는 시점에 밖에 id 값을 알 수가 없음. 따라서 JPA는 IDNETITY strategy의 경우 batch insert를 하지 않고 persist 시점에서 즉시 insert sql을 실행함.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
privaate Long id;
SEQUENCE strategy
- 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트
- 주로 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용한다.
@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;
...
}
속성 | 설명 | 기본값 |
---|---|---|
name | 식별자 생성기 이름 | 필수 |
sequenceName | 데이터베이스에 등록되어 있는 시퀀스 이름 | |
initialValue(DDL) | 시퀀스 ddl을 생성할 때 처음 시작하는 수 지정 | 1 |
allocationSize | 시퀀스 한번 호출에 증가하는 수 | 50 |
catalog, schema |
allocationSize의 경우 한번 시퀀스를 호출할 때 증가하는 수를 말한다. 즉 한번 호출했을 때 50까지 호출을 하는 것이 default이며, 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 반드시 1로 설정해두어야 한다.
TABLE strategy
- 키 생성 전용 테이블을 만들어서 데이터베이스 시퀀스처럼 사용하는 전략
- 모든 데이터베이스에 적용할 수 있지만 성능상 테이블을 생성해서 직접 만들기 때문에 문제가 될 수 있다.
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key (secuence_name)
)
@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;
...
}
속성 | 설명 | 기본값 |
---|---|---|
name | 식별자 생성기 이름 | 필수 |
table | 키생성 테이블 명 | |
pkColumnName | 시퀀스 컬럼 명 | |
valueColumnName | 시퀀스값 컬럼 명 | next_val |
initialValue | 초기값 | 0 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수 | 50 |
catalog, schema | ||
uniqueConstraints(DDL) | 유니크 제약조건 설정 가능 |
권장하는 식별자 전략
- 기본키 제약 조건 : null이 아니어야 하고, 유일해야 하고, 변하면 안된다.
- 자연키 중에서는 이를 완전히 만족시키는 자연키를 찾기 힘들기 때문에 대체키를 사용하자.
- 권장 : Long 형 + 대체키 + 키 생성 전략 사용
'JAVA > JPA' 카테고리의 다른 글
JPA 모든 N+1 발생 케이스과 해결책 (0) | 2021.11.23 |
---|---|
연관관계 매핑 기초 (0) | 2021.08.12 |
영속성 관리 - 내부 동작 방식 (0) | 2021.08.09 |
JPA 소개 및 특징 (0) | 2021.08.09 |
- Total
- Today
- Yesterday