본문 바로가기
개발공부 개발새발/DB

JPA) 엔티티매핑(객체와 테이블, 필드와 컬럼, 기본 키)

by 휴일이 2022. 11. 24.




엔티티 매핑!

객체와 테이블 매핑
@Entity , @Table

필드와 컬럼
@Column

기본 키
@Id

연관관계 매핑
@ManyToOne, @JoinColumn




객체와 테이블 매핑?
@Entity가 붙은 클래스는 JPA가 관리한다, 엔티티라고 부른다
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수

- 기본 생성자 필수
- final, enum, interface, inner 클래스 사용 불가
- 저장할 필드에 final 사용 불가(수정이 안대자낭)


@Entity는 기본값이 클래스 이름 그대로, @Entity(name="")도 가능하긴 함
Entity name은 JPA에서 얘를 관리할 때 쓸 이름

@Table 엔티티와 매핑할 테이블명을 지정한다



데이터베이스 스키마 자동 생성

<property name="hibernate.hbm2ddl.auto" value="create" />

애플리케이션 실행 시점에 자동 생성됩니다
객체 매핑을 다 해놓으면 App 시작 시점에 Table 자동 생성도 가능

DB 방언을 활용해서 DB에 맞는 적절한 DDL 생성
ㄴ 개발에서만 쓰세요, 운영서버에서는 사용 X
ㄴ 다듬으세용

방언에 맞춰서 실행해줌니당



주의)
!!!운영 장비에는 절대 CREATE, CREAT-DROP, UPDATE 사용 금지!!!
개발 초기 단계에는 create 또는 update
테스트 서버에는 update 또는 validate - 가급적 쓰지마세요
스테이징과 운영 서버는 validate 또는 none - 가급적 쓰지마세요



DDL 생성 기능
ㄴ Unique 제약 조건
ㄴ 실행 자체에 영향 없음 DDL 생성에만 도움을 줌





------------------

필드와 컬럼 매핑


@Id
-> Primary Key

@Column
-> DB컬럼명과 엔티티 필드명이 다를 때 @Column(name = "name")

Integer 타입으로 했다면?
-> Integer와 가장 적절한 숫자 타입이 선택됨


@Enumerated(EnumType.STRING)
-> Enum 타입 쓰기 가능

@Temporal(TemporalTYPE.TIMESTAMP)
ㄴ DATE, TIME, TIMESTAMP 알려줄 때

@Lob
ㄴ varchar를 뛰어넘는 더 큰 단위를 사용할 때

@Transient
ㄴ 얘는 DB랑 관련 없는 필드야




@Column 속성?
name -> 필드와 매핑할 테이블의 컬럼 이름, 기본 필드명
inserttable -> 등록 가능 여부 , 기본 true
updatable -> 변경 가능 여부 , 기본 true
nullable -> null허용 여부 설정, false는 not null
unipue -> 유니크 제약 조건
columnDefinition -> DB 컬럼 정보를 직접 줄 수 있음, @Column( columnDefinition = varchar(100) default 'EMPTY' )
length -> 문자 길이 제약 조건, STRING에서만 사용
<BigDecimal(BigInteger) 타입에만 사용>
precision -> 소수점을 포함한 전체 자릿수 지정
scale -> 소수점의 자리수



@Enumerated 주의
EnumType.ORDINAL : enum 순서를 DB에 저장(기본값)
!! String 얘만 씀 !!
EnumType.String : enum 이름을 DB에 저장
!! String 얘만 씀 !!



@Temporal
날짜 타입을 매핑할 때 사용, 최신 하이버네이트는 지원하니까 걍~ 거의 안 씀



@Lob
필드가 문자면 CLOB, 나머지는 BLOB






-----------------

기본 키 매핑

@Id
직접 할당


@GeneratedValue
자동 할당

@GeneratedValue의 전략




strategy = "IDENTITY"
기본 키 생성을 DB에 위임(auto-increment)
: DB에 INSERT를 해봐야 ID값을 알 수 있음
: persist를 호출한 시점에 INSERT 쿼리가 날라감 (commit하기 전에도 날라감)


strategy = "SEQUENCE"
시퀀스 대상 컬럼은 Long 타입으로 씁시다
시퀀스 직접 만들고 싶다면? @SequenceGenarator를 써서 가능하긴 해요잉

@SequenceGenarator ( name = "필드에서 사용할 시퀀스 이름", sequenceName = "DB에 넣을 시퀀스 이름")
class 어쩌구

-방법
@Id
@GeneratedValue(strategy = GenerateType.SEQUENCE, genarator = "클래스에 붙은, 필드에서 사용할 시퀀스 이름")
필드(변수)

SEQUENCE 전략에서는 DB 시퀀스 값을 알아야 INSERT할 때 새 시퀀스를 줄 수 있음
시퀀스 값 주세요 쿼리 호출
그 다음 persist 하고, 영속성 컨텍스트 호출
버퍼링 주다가 commit 으로 날려주기 가능

미리 allocationSize(시퀀스 한 번 호출에 증가하는 수) -> 성능 최적화
로 미리 n개(50 기본) 미리 가져와서 시퀀스에 메모리 하나하나 올림




strategy = "TABLE"
키 생성 전용 테이블을 만들어서, DB 시퀀스 흉내냄
장점:모든 DB 적용 가능
단점:성능이 떨어짐
- 운영에서는 잘 안 씀니다



권장하는 식별자 전략
- 기본 키 제약 조건 : NOT NULL, 유일, 변하면 안 됨
ㄴ 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다, 대체키(비즈니스와 전혀 상관없는 키)를 사용하자
ㄴ 주민번호도 기본키로 적절하지 않다
권장 : Long + 대체키(시퀀스) + 키 생성 전략


728x90