[JPA/김영한] 엔티티 매핑은 어떻게 이뤄질까?

수영·2021년 9월 15일
1

JPA 공부!

목록 보기
3/9

이 글은 김영한님의 JPA 강의 중 4장을 듣고 정리한 내용입니다 :)
강의 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
교재 : 자바 ORM 표준 JPA 프로그래밍🤷‍♀️

⚡@Entity로 객체와 테이블을 매핑해준다!

  • 기본생성자가 필수로 있어야 함
  • @Entity가 붙으면 JPA가 관리
  • @Table (name=" ") 쓰면 테이블 이름을 정해주는 것 (객체랑 테이블이랑 이름이 다를 경우)

🎯 JPA의 DB 스키마 DDL 알아보기~

  • 여기서 DDL이란? 데이터의 전체 골격(테이블)을 생성/수정/삭제하는 역할의 언어
  • 어플리케이션 실행 시점에 자동 생성
<property name="hibernate.hbm2ddl.auto" value="create"/>

- create : 삭제하고 다시 생성
- create-drop : 종료 시점에 drop
- update : 변경된 내용만 반영
- validate : 바꾸지는 않고, 엔티티-테이블이 정상 매핑되었는지 확인
- none : 아무것도 안함
  • 운영 서버 : validate, none (특히 실무에서 create, create-drop, update 절대 사용X - 이전 데이터 날라가니까!!)
  • 개발 초기 : create, update, 테스트 서버 : update, validate(테스트에서도 데이터 날리면 안됨)

- ??
@Column(unique = true, length = 10)으로 제약 조건 추가
JPA 실행 매커니즘에는 영향을 주지 않고 DB에만 영향을 줌, (DDL 생성 기능)
반면 @Table (name=" ")은 insert 쿼리에 영향을 줌


🚩 필드와 컬럼 매핑할 때,

package hellojpa;
import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
@Table (name="MBR")          //DB에 매핑할 이름
public class Member {
@Id
private Long id;

@Column(name = "name")       //DB에 표시되는 이름
private String username;

private Integer age;         //알아서 디비 타입과 매핑

@Enumerated(EnumType.STRING) //DB에 ENUM타입 매핑 시
private RoleType roleType;

@Temporal(TemporalType.TIMESTAMP) //DB에 날짜관련 매핑 시
private Date createdDate;

@Transient                   //DB에 넣지 않는 데이터
private int count;

@Lob                         //varchar보다 큰 타입을 넣고 싶은 경우
private String description;  //문자면 CLOB, 나머지는 BLOB으로 매핑
//Getter, Setter…
}

Enum 타입 사용할 때는 String으로 저장하자

  • enum 순서를 숫자로 데이터베이스에 저장 시, 항목이 변경,추가되면 숫자가 꼬임

→ 꼭 String 타입으로 저장

// EnumType.ORDINAL: enum 순서를 숫자로 데이터베이스에 저장
// EnumType.STRING: enum 이름을 데이터베이스에 저장

@Enumerated(EnumType.STRING) //DB에 ENUM타입 매핑 시
private RoleType roleType;

날짜 타입 사용할 때 구버전이면

// 최신 버전
private LocalDate createdAt;

//구 버전
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

TemporalType.DATE: 날짜 (예시 2021-09-09, date)
TemporalType.TIME : 시간 (예시 11:11:11, time)
TemporalType.TIMESTAMP : 날짜, 시간 (예시 2021-09-09 11:11:11)

@Column에 붙는 속성들


🔺기본키 매핑할 때는

: Long + 대체키 + 키 생성 전략으로~!

@Id
@GeneratedValue(strategy = GeneraionType.IDENTITY)
private Long id;

1. Long

  • 아이디는 데이터 범위가 넓은 Long 추천
    Integer(10억 제한) 썼다가 나중에 타입 바꾸는 게 더 불편하고, 요즘은 둘의 성능 차이가 크지 않기 때문에!
  • Primitive(long)가 아닌 Wrapper(Long) 타입을 쓰는 이유? → 0!
    래퍼 타입은 nullable 하기에 값이 없으면 null, 0은 키값 0을 의미
    원시 타입은 기본이 0이기에, 값이 없어서 0인지 키값이 0인지 구분 힘듦 → int price

2. 대체키

주민번호를 PK로 쓸 경우, 다른 테이블의 FK도 다 주민번호로...

→ DB 마이그레이션 할 때 불편함! → 테이블마다 주민번호를 다 넣어주고 바꿔야되기에
→ 비즈니스 관련 값 말고 그냥 랜덤 키값 Long으로 하기를 권장

3. 키 생성 전략 4가지

@GeneratedValue ( ) : 자동 생성

  • (strategy = GeneraionType.AUTO) : DB 방언에 맞는 SQL 나옴 (오라클, h2, MySQL등 각각에 맞게)

  • (strategy = GeneraionType.SEQUENCE) : 그 다음 순서대로 자동 생성
    ⇒ ORACLE, @SequenceGenerator 필요

  • (strategy = GeneraionType.TABLE) : 키 생성 전용 테이블을 따로 만듦, 데이터베이스 시퀀스를 따라함 → 운영에서는 딱히 쓰지 않음
    ⇒ 모든 DB에서 가능, @TableGenerator 필요

  • (strategy = GeneraionType.IDENTITY) : 기본 키 생성을 DB한테 시킴
    ⇒ MySQL

  • 다시 봐야함 - 4가지 방식
    영속성 컨텍스트에 있으려면 PK값이 있어야되는데, PK를 자동생성으로 하면 디비에 들어가야 생성되므로 문제
    → Identity에서만
    트랜잭션 커밋이 아니라, persist 할때 바로 insert 쿼리를 날림
    em.persist할 때 → PK값을 만듦
    시퀀스는 아이디값 생성 후,,,

profile
🎵🎵🎵🎶🎵

0개의 댓글