엔티티 매핑

최주영·2024년 12월 10일
0

JPA

목록 보기
3/5

@Entity : DB의 특정테이블과 연결되는 JAVA의 객체로 JPA가 관리하는 엔티티를 의미한다

  • JPA를 사용해서 테이블과 매핑할 클래스는 반드시 @Entity 를 사용해야함
  • @Entity 를 사용하려면 기본 생성자가 필수로 존재해야함
  • 선언부에 @Entity 어노테이션을 설정
  • 클래스명은 테이블, 필드는 컬럼으로 DB와 매핑

@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

그러면 IDENTITYSEQUENCE 차이점은 정확히 무엇일까?

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
}
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글