roleType은 자바의 enum을 사용해서 회원의 타입을 구분. 일반 회원은 USER, 관리자는 ADMIN. 자바 enum을 사용하고 싶다면 @Enumerated 어노테이션으로 매핑해서 사용합니다. createDate는 자바의 날짜 타입을 @Temporal 어노테이션을 사용합니다. description은 길이 제한이 없어서 VARCHAR 타입 대신 CLOB 타입으로 저장한다. @Lob 어노테이션을 사용하면 CLOB, BLOB 타입으로 매핑할 수 있습니다.
@Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@Lob
private String description;
create : 기존 테이블을 삭제하고 새로 생성합니다. DROP + CREATE
create-drop : create 속성에 추가로 애플리케이션을 종료할 때 DDL을 제거합니다.
update : 데이터베이스 테이블과 엔티티 매핑정보를 비교해 변경사항만 수정합니다.
validate : 데이터베이스 테이블과 엔티티 매핑정보를 비교해 차이가 있으면 경고를 남기고 애플리케이션을 실행하지 않습니다. (DDL을 수정하지 않는 설정입니다.)
none : 자동 생성 기능을 사용하지 않으려면 hibernate.hbm2ddl.auto 속성을 삭제허가너 유효하지 않는 옵션 값으로 지정하면 됩니다.
IDENTITY : 기본 키 생성은 데이터베이스로 위임합니다.
SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당합니다.
TABLE : 키 생성 테이블을 사용합니다
키 생성 전략을 사용하려면 hibernate.id.new_generator_mapping=true 속성을 추가해야 합니다.
데이터베이스 시퀀스는 고유 값을 순서대로 생성하는 데이터베이스의 오브젝트 입니다. SEQUENCE 전략에 따라 동작 방법이 다릅니다.
(1) 시퀀스 매핑 코드
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BOARD_SEQ_GENERATOR")
private Long id;
키 생성 전략을 GenerationType.SEQUENCE로 설정하고 generator = "BOARD_SEQ_GENERATOR"로 방금 등록한 시퀀스 생성기를 선택했습니다. id 식별자 값은 BOARD_SEQ_GENERATOR 시퀀스 생성기에서 할당합니다.
이 방법을 사용시 내부 동작은 엔티티를 데이터테이스에 저장후 식별자를 조회하여 엔티티 식별자에 할당합니다.
SEQUENCE 전략은 데이터베이스 시퀀스를 통해 식별자를 조회하는 추가 작업이 필요합니다. 그러므로 데이터베이스와 2번 통신하게 됩니다.
1. 식별자를 구하려고 데이버테이스 시퀀스를 조회합니다 : SELECT BOARD_SEQ.NEXTVAL FROM DUAL
2. 조회한 시퀀스를 기본 키 값으로 사용해 데이터베이스에 저장합니다 : INSERT INTO BOARD...
SEQUENCE 최적화 방법
JPA는 시퀀스 접근 횟수를 줄이기 위하여 @SequenceGenerator.allocationSize를 사용합니다. 간단히 설명하면 설정한 값만큼 한 번에 시퀀스 값을 증가시키고 나서 그만큼 메모리에 시퀀스 값을 할당합니다. 예를 들어 allotaionSize 값이 50이면 시퀀스를 한 번에 50 증가시킨 다음 1~50까지는 메모리에서 식별자를 할당합니다. 그리고 51이 되면 시퀀스 값을 100으로 증가하여 51~100까지 메모리에 식별자를 할당합니다.
이 방법은 시퀀스를 선점하여 여러 JVM이 동시에 동작해도 기본 키 값이 충돌하지 않는 장점이 있습니다. 반면 데이터베이스 직접 접근해서 데이터를 등록할 때 시퀀스 값이 한번에 많이 증가한다는 점을 알고 있어야 합니다. 이것이 부담스럽고 INSERT 성능이 중요하지 않다면 allocationSize 값을 1로 설정하면 됩니다.
추가로 hibernate.id.new_generator_mappings 속성을 true로 설정해야 위 내용의 최적화 방법이 적용됩니다.
(2) 시퀀스 사용 코드
Board board = new Board();
em.persist(board);
SEQUENCE 전략은 em.persist()를 호출하면 데이터베이스 시퀀스를 사용하여 식별자를 조회합니다. 조회된 식별자를 엔티티에 할당하고 엔티티를 영속성 컨텍스트에 저장합니다. 그리고 트랜잭션을 커밋하여 플러시가 발생하면 엔티티를 데이터베이스 저장합니다.
name : 식별자 생성기 이름
sequenceName : 데이터베이스에 등록되어 있는 시퀀스 이름
initialValue : DDL 생성 시에만 사용이 가능. 시퀀스 DDL을 생성할 때 처음 시작하는 수를 지정합니다.
allocationSize : 시퀀스 한번 호출에 증가하는 수
catalog, schema : 데이터베이스 catalog, schema 이름
매핑할 DDL
create sequence [sequenceName]
start with [initialValue] increment by [allocationSize]
TABLE 전략을 사용하기 위해서는 아래처럼 키 생성 용도로 사용할 테이블을 만들어야 합니다.
Table 전략 키 생성 DDL
create table TEMP_SEQUENCE (
sequence_name varchar(255) not null;
next_val bigint,
primary key (sequence_name)
)
sequence_name 컬럼을 시퀀스 이름으로 사용하고 next_val 컬럼을 시퀀스 값으로 사용합니다.
TABLE 전략 매핑 코드
@Entity
@TableGenerator(
name = "BOARD_SEQ_GENERATOR",
table = "TEMP_SEQUENCE"
pkColumnValue = "BOARD_SEQ", allocationSize = 1)
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "BOARD_SEQ_GENERATOR")
private Long id;
}
@TableGenerator를 사용해서 테이블 키 생성기를 등록해야 합니다.
여기서는 BOARD_SEQ_GENERATOR 라는 이름의 테이블 키 생성기를 등록하고 방금 생성한 TEMP_SEQUENCE 테이블을 키 생성용 테이블로 매핑하였습니다. 그리고 TABLE 전략을 사용하기 위해 GenerationType.TABLE을 선택했습니다. 그리고 @GeneratedValue.generator 에 방금 만든 키 생성기를 지정했습니다. 이제부터는 id 식별자 값은 BOARD_SEQ_GENERATOR 테이블 키 생성기가 할당됩니다.
데이터베이스 종료도 많고 기본키 만드는 방법도 다양합니다. GenerationType.AUTO는 선택한 데이터베이스에 맞게 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택합니다.
AUTO 전략의 장점은 데이터베이스를 변경해도 코드 수정할 필요가 없습니다. AUTO를 사용할 때 SEQUENCE 나 TABLE 전략이 선택되면 시퀀스나 키 생성용 테이블을 미리 만들어 두어야 합니다.
데이터베이스 기본 키 설정 3가지 권장사항
1. null 값은 허용하지 않는다.
2. 유일해야 한다.
3. 변해서는 안된다.
테이블의 기본 키를 선택하는 전략은 2가지
(1) 자연키 : 비즈니스에 의미가 있는 키 (주민번호, 이메일, 전화번호)
(2) 대리키 : 비즈니스에 관련 없는 임의로 만들어진 키 (오라클 시퀀스, auto_increment, 키 생성 테이블 이용)
양방향 연관관계 (mappedBy, @OneToMany, @ManyToOne) (1) | 2024.01.15 |
---|---|
매핑 어노테이션 (@Enumerated, @Temporal, @Lob, @Transient, @Access) (0) | 2024.01.12 |
클래스 상속 (생성자 호출) 자바 (1) | 2024.01.10 |
어노테이션 (메타데이터 리플랙션 @Retention @Target) (0) | 2024.01.09 |
열거 타입 정리 (JAVA) (1) | 2024.01.08 |
댓글 영역