필드와 컬럼 매핑
@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,Timestamp3가지 타입이 존재한다.@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
@LobBLOB,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 |