필드와 컬럼 매핑
@Column
- 컬럼 매핑
@Column(name = "{컬럼명}")
형태로 사용한다.- 속성
name
- 매핑할 테이블의 컬럼 이름 (기본값: 객체의 필드명)
insertable
,updatable
- 등록, 변경 가능 여부 (기본값: True)
@Column(insertable = true, updatable = false)
nullable
(DDL)null
값의 허용 여부를 설정한다.false
로 설정하면 DDL 생성 시에not null
제약조건이 붙는다.@Column(nullable = false)
unique
(DDL)@Table
의uniqueConstraints
와 같지만 한 컬럼에 간단히 유니크 제약조건을 걸때 사용.- 컬럼에 사용 시 유니크키의 이름을 설정하기 힘들기 때문에 잘 사용하지 않는다.
columnDefinition
(DDL)- 컬럼정보를 직접 줄 수 있다.
@Column(columnDefinition = "varchar(1000) default 'EMPTY'")
length
(DDL)- 문자 길이 제약조건, String 타입에만 사용한다.
precision
(DDL),scale
(DDL)BigDecimal
타입에서 사용한다(BigInteger
도 사용할 수 있다).precision
은 소수점을 포함한 전체 자 릿수를,scale
은 소수의 자릿수 다. 참고로double
,float
타입에는 적용되지 않는다. 아주 큰 숫자나 정밀한 소수를 다루어야 할 때만 사용한다.- 기본값: precision = 19, scale = 2
@Temporal
- 날짜 타입 매핑
Date
,Time
,Timestamp
3가지 타입이 존재한다.@Temporal(TemporalType.TIMESTAMP)
형태로 사용한다.LocalDate
,LocalDateTime
을 사용할 때는 생략 가능하다.- 속성
- value
TemporalType.DATE
- 날짜, 데이터베이스 Date 타입과 매핑 (yyyy-MM-dd)
TemporalType.TIME
- 시간, 데이터베이스 Time타입과 매핑 (HH:mi:ss)
TemporalType.TIMESTAMP
- timestamp 타입과 매핑 (yyyy-MM-dd HH:mi:ss)
- value
@Enumerated
- enum 타입 매핑
@Enumerated(EnumType.STRING)
형태로 사용한다.- 속성
- value
EnumType.ORDINAL
- enum의 순서를 데이터베이스에 저장한다. (0,1,2 형태로 순서를 저장한다.)
EnumType.STRING
- enum의 이름을 데이터베이스에 저장한다.
- ORDINAL 사용하지 않는것을 권장!!! 타입이 추가되서 순서가 꼬일경우... 망합니다.
- value
@Lob
BLOB
,CLOB
타입으로 매핑된다.- 문자 타입일 경우
CLOB
타입으로 매핑, 나머지는BLOB
매핑
@Transient
- 해당 필드를 컬럼에 매핑하지 않음(엔티티 내에서 DB에 컬럼과 매핑되지 않은 필드로 사용한다.)
기본 키 매핑
@Id
: 직접 키값 할당 시 사용한다.@GeneratedValue
: 자동 생성(키값을 자동으로 할당 시 사용한다.)- 속성
IDENTITY
- 기본 키 생성을 데이터베이스에 위임
- MySQL, PostgreSQL, SQL Server, DB2에서 사용 (예: MySQL의
AUTO_INCREMENT
) - JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
AUTO_INCREMENT
는 데이터베이스에INSERT SQL
을 실행 한 이후에ID
값을 알 수 있음IDENTITY
전략은em.persist()
시점에 즉시INSERT SQL
실행 하고DB
에서 식별자를 조회
SEQUENCE
- 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예: 오라클 시퀀스)
- 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
@SequenceGenerator
를 통해 시퀀스 정의 해줄 수 있고 아닐경우hibernate_sequence
를 사용한다.
TABLE
- 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스처럼 사용하는 전략
@TableGenerator
필요- 모든 데이터베이스에 적용이 가능하나 별도의
select
가 한번 더 생기기 때문에 성능에 영향이 있다.
AUTO
- 방언(
Dialect
)에 따라 자동 지정, 기본값
- 방언(
- 속성
성능 최적화 전략
IDENTITY
전략IDENTITY
전략을 사용 시DB
에Insert
가 되어야PK
값을 알 수 있다.em.persist()
를 호출하는 시점에 바로DB
에 Insert SQL을 전송한다. 영속성 컨텍스트에PK
값으로 사용하기 위함.@Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; }
SEQUENCE
전략- 트랜젝션 커밋 전에 데이터베이스를 통해서
Sequence
의 값을 조회해서 온다. - 미리 조회를 해서 가져오기 때문에 성능 문제가 발생한다. 매번 em.persist()를 할때마다 네트워크를 통해 시퀀스 조회 쿼리가 발생할 수 있다.
- 위와 같은 문제는
allocationSize
설정을 통해서 성능을 증가 시킬 수 있다. allocationSize
의 기본값은 50이다. 이 방식은 데이터베이스의 시퀀스 값은 50씩 미리 증가를 시켜놓고 JPA내부 동작에 의해서 메모리를 참조하여서 순차적으로 증가 시킨다.- 이 방식은 미리 메모리에 가지고 와서 50개의 row가 저장하기 전에는 별도의 select 쿼리를 실행하지 않는다. 즉, 최초 저장시 그리고
allocationSize
를 통해 증가시킨 값에 도달했을 경우에만 select 쿼리를 2번 날린다. @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; }
- 트랜젝션 커밋 전에 데이터베이스를 통해서
@Id
키의 필드 타입은 WrapperClass를 사용하자. (자동 매핑 전략을 사용 시)
int
,long
등의 자바 기본 Primitive type을 사용시 자바에서는 기본 값 이라는것을 할당한다.- 숫자형 타입이기 때문에 0이라는 값을 기본값으로 할당이 되고 이 값으로 인해서 기본키의 값이 있는것으로 판단하여 장애가 발생할 수 있기 때문에
null
체킹을 위해서 WrapperClass를 사용하는것을 권장한다. (Integer
보다는Long
을 이용하자.)
권장하는 식별자 전략
- 기본키 제약 조건: Not Null, 불변성, 유일성
- 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자. (예: 주민등록번호, 전화번호 ...)
- 주민등록번호를 키로 사용하던중 주민등록번호를 사용하면 안되는 보안전략이 생기게 되면... ... Holy..........
- 권장하는 키 전략은
Long
+ 대체키(시퀀스, uuid) + 키를 조합한 생성전략을 사용하는 부분을 권장한다.
'Spring > JPA' 카테고리의 다른 글
스키마 자동 생성(Auto DDL) (0) | 2023.06.15 |
---|---|
엔티티 매핑 (0) | 2023.06.15 |
JPA 란 무엇이고 왜 사용해야 하는가 (0) | 2021.12.24 |
엔티티 매핑과 기본키 전략 (0) | 2021.12.23 |
영속성 컨텍스트와 플러시 (0) | 2021.12.23 |