✅ @Entity
: DB의 특정테이블과 연결되는 JAVA의 객체로 JPA가 관리하는 엔티티를 의미한다
@Entity
를 사용해야함@Entity
를 사용하려면 기본 생성자가 필수로 존재해야함@Entity
어노테이션을 설정✅ @Table
: 엔티티와 매핑할 테이블을 지정
✅ @Column
: 엔티티와 매핑할 DB 컬럼 지정
-> @Column 속성들
✅ @Enumerated
: enum 타입을 사용할 때 지정 -> 기본 값이 EnumType.ORDINAL
주의 점 : EnumType.ORDINAL
타입은 사용하지 않아야함 -> Enum 순서를 DB에 저장 (0부터 시작)
-> Enum 값을 잘못 추가하면 순서가 안맞는 예외가 발생 -> EnumType.String
을 사용해서 해결
✅ @Temporal
: 날짜 타입을 사용할 때 지정 (DATE, TIME, TIMESTAMP) 3가지 존재
✅ @Transient
: 엔티티와 매핑하지 않을 때 사용 (자바에서만 사용)
✅ @Lob
: clob, blob 타입 지정할 때 사용하며 반환 타입에 대해서 lob 형태가 나뉨
✅ @Id
: 기본키 직접할당
✅ @GeneratedValue
: 기본키 자동 생성
@GeneratedValue
전략에는 4가지 전략이 존재
IDENTITY
SEQUENCE
TABLE
AUTO
IDENTITY
: MYSQL과 같이 시퀀스를 제공하지 않고, 키 값이 자동으로 증가해야할 때 사용@id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
JPA는 보통 트랙잭션 커밋 시점에 INSERT 문이 실행되지만
자동 증가 (AUTO_INCREMENT
) 는 데이터베이스에 INSERT SQL을 실행한 이후에 값을 알 수 있어서
IDENTITY
전략은 예외적으로persist
메소드 호출 시점에 INSERT SQL을 실행함
SEQUENCE
: DB Sequence를 사용해 기본 키를 할당하는 방식으로 오라클에서 사용SequenceGenerator
는 테이블마다 시퀀스를 따로 관리할 때 사용시퀀스 전략은
persist
호출 전에 먼저 DB Sequence를 먼저 조회하는 전략이다
하지만persist
호출이 많아지면 DB Sequence에 접근 횟수가 많아져서 성능이 나빠질 것이다
그것을 방지하기 위해서 allocationSize
속성을 사용해서 미리 시퀀스 사이즈를 땡겨온다
allocationSize
의 기본값은 50으로
설정 값 만큼 한 번에 시퀀스를 증가 시키고, 그만큼 Memory에 시퀀스 값을 할당한다.
그러면 시퀀스 값이 증가되도 DB Sequence에 접근 하지 않고 Memory에 저장되어 있는 시퀀스를 할당
@Entity
@SequenceGenerator(
name = "USER_SEQ_GENERATOR"
, sequenceName = "USER_SEQ"
, initialValue = 1
, allocationSize = 1
)
public class User {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE
, generator = "USER_SEQ_GENERATOR"
)
private long id;
}
TABLE
: 키 생성 전용 테이블을 만들어서 DB 시퀀스를 흉내내는 전략으로다음과 같이 키 생성 전용 테이블을 생성한 후 @TableGenerator
사용해 Entity를 Mapping한다.
create table JOO_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
)
@Entity
@TableGenerator(
name = "JOO_SEQ_GENERATOR", // 매핑할 이름
table = "JOO_SEQUENCES", // 키 생성될 테이블 명
pkColumnValue = "JOO_SEQ", allocationSize = 1) // pkColumnValue = db에 저장될 시퀀스 컬럼 이름
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "JOO_SEQ_GENERATOR")
private Long id;
AUTO
: DB에 맞춰서 자동으로 정해줌 -> EX) 오라클이면 SEQUENCE
, MYSQL은 IDENTITY
그러면 IDENTITY
와 SEQUENCE
차이점은 정확히 무엇일까?
IDENTITY 전략은 먼저 Entity를 DB에
INSERT
후에, 식별자를 조회하는 전략
SEQUENCE 전략은
persist
호출 전에 먼저 DB Sequence를 먼저 조회한다.
그 후 조회한 식별자를 Entity에 할당한 후 Entity를영속상태
로 저장한다.
그 후 Transaction을 Commit하여Flush
가 발생할 때 해당 Entity를 DB에INSERT
하는 전략
기본키는 null이 아니고, 유일해야하며 변하면 안됨
즉 미래에도 계속 유지되어야 한다
주민등록번호를 기본키로 설정했을 때, 미래에 주민등록번호가 보안상의 이유로 제외하라는
요구가 있을 경우 많은 문제점이 생긴다
그래서 식별자는 구별할 때 Long형 + 대체키 + 키 생성전략(SEQUENCE or IDENTITY)
전략을 사용하자
다음은 위를 종합한 정리한 내용이니 참고하자
@Entity // Member 클래스는 jpa를 사용한다는 뜻
@Table("mbr") // DB에 있는 mbr 이라는 테이블과 매핑한다는 뜻
public class Member{
@Id // 기본키 직접할당
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "dbname", nullable = false)
// 자바객체는 username이 이름이지만 DB에서는 dbname이라는 컬럼일 때 사용, not null 제약조건 추가
private String username;
@Enumerated(EnumType.STRING)
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP) // 날짜 + 시간
private Date createDate;
// 만약 하이버네이트 최신버전을 사용하면 LocalDate, LocalDateTime 을 사용해서 @Temporal 생략 가능
private LocalDateTime testLocalDateTime;
@Lob
private String info; // clob -> (큰범위의) 문자열 저장하는 타입
@Lob
private byte[] dataSample; // blob -> (바이너리) 파일저장하는 타입
}
public enum RoleType{
USER,ADMIN
}