JPA 엔티티 매핑

jungnoeun·2022년 12월 16일
0

spring

목록 보기
22/24

JPA 알아야 할 내용

  • jpa 내부 동작 방식(영속성 컨텍스트)
  • 설계적인 측면(객체와 관계형 데이터를 어떻게 매핑해서 쓰는지)
  • 연관관계 매핑
    ->어떤것이 어떤 것에 속해있는지



엔티티 매핑

객체와 테이블 매핑

@Entity

  • @Entity가 붙은 클래스는 테이블과 매핑할 클래스
  • 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
    → 리플랙션 같은 다양한 기술을 써서 객체를 프록싱하기도 하는데 이때 필요.
  • 저장할 필드에 final 사용 X
    → 디비에 저장할 필드에는 final을 쓰면 안된다.
  • 속성: name
    - JPA에서 사용할 엔티티 이름을 지정한다.
    - 기본값: 클래스 이름을 그대로 사용(예: Member)

@Table

  • 엔티티와 매핑할 테이블을 지정
  • 아래 코드와 같이 설정하면 insert 쿼리가 나갈때 insert into MBR ... 로 나간다.
@Table(name="MBR")
public class Member{}





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

  • JPA는 매핑정보만 보고 어떤 쿼리, 테이블을 생성해야 하는지 알 수 있다. 그래서 JPA는 어플리케이션 로딩 시점에 DB 테이블을 생성하는 기능을 지원해준다.
  • DDL을 애플리케이션 실행 시점에 자동 생성
    → 애플리케이션 로딩 시점에 create문으로 DB를 생성하고 시작할 수 있다.
    처음에 객체 매핑해놓으면 애플리케이션 뜰 때 필요한 테이블들을 만들어준다.
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
    → 운영에서는 사용하면 안된다.

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

hibernate.hbm2ddl.auto

  • create : 기존테이블 삭제 후 다시 생성 (DROP + CREATE)
  • create-drop : create와 같으나 종료시점에 테이블 DROP
  • update : 변경분만 반영(운영DB에는 사용하면 안됨)
    -> 지우는 작업은 안되고, 추가하는 작업만 가능하다.
  • validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
  • none : 사용하지 않음

데이터베이스 스키마 자동 생성 - 주의

  • 운영 장비에는 절대 create, create-drop, update 사용하면 안된다.
  • 개발 초기 단계는 create 또는 update
  • 테스트 서버는 update 또는 validate
  • 스테이징과 운영 서버는 validate 또는 none
    ⇒ 로컬 피씨에서만 자유롭게 하고, 여러명이 쓰는 개발 서버나 스테이징이나 운영서버에는 가급적 쓰지 않는것을 권장한다.

DDL 생성 기능

  • 제약조건 추가: 회원 이름은 필수, 10자 초과X
    @Column(nullable = false, length = 10)
  • 유니크 제약조건 추가
    @Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )})
  • DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.





필드와 컬럼 매핑

매핑 어노테이션 정리

hibernate.hbm2ddl.auto

@Column - 컬럼 매핑

@Temporal - 날짜 타입 매핑

날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용
참고: LocalDate, LocalDateTime을 사용할 때는 생략 가능(최신 하이버네이트 지원)

@Enumerated - enum 타입 매핑

Enum타입을 쓸때는 기본이 ORDINAL이다. ORDINAL과 STRING을 쓸 수 있는데,

  • EnumType.ORDINAL: enum 순서를 데이터베이스에 저장
  • EnumType.STRING: enum 이름을 데이터베이스에 저장
    → ORDINAL을 사용하면 안되는 이유:
    ⇒ ENUM에 나중에 값이 하나 추가 되어서 USER, ADMIN에서 GUEST, USER, ADMIN 으로 바뀌면 디비에 값을 저장하는데 혼란이 발생한다.

@Lob - BLOB, CLOB 매핑

@Lob private String description;
→ DB에 varchar보다 큰 컨텐츠를 넣고 싶으면 @Lob을 넣으면 된다.
매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑

  • CLOB: String, char[], java.sql.CLOB
  • BLOB: byte[], java.sql. BLOB

@Transient - 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)

@Transient private int temp;
-> DB랑 관련없이 메모리에서만 계산하고 싶은 변수가 있을경우, @Transient를 붙여주면 된다. 사용법은 위와 같다.

유니크 제약 조건

unique(DDL) 은 잘 안쓴다.

  • 이름이 랜덤으로 생성돼서 쓰기 어려워 대신 @Table(uniqueConstraints) 으로 쓴다






기본 키 매핑

기본 키 매핑 어노테이션

  • @Id
  • @GeneratedValue

기본 키 매핑 방법

  • 직접 할당: @Id만 사용
  • 자동 생성(@GeneratedValue)
    → 값을 자동으로 할당해주는 방법
  • IDENTITY: 데이터베이스에 위임, MYSQL의 AUTO_INCREMENT
    • 영속성 컨텍스트에서 관리되려면 무조건 pk값이 있어야 한다. 근데 IDENTITY 전략은 pk값이 데이터베이스에 들어간후에나 pk값을 알 수 있다. 그래서 JPA는 pk값이 없으니까 1차 캐시에 값을 넣을 수 없다. 그래서 IDENTITY 전략에서만 예외적으로 em.persist()를 호출한 시점에 디비에 insert쿼리를 날려버린다. (원래 커밋하는 시점에 쿼리가 날아간다.)
	//Member
	@Entity // JPA를 사용하는 애라고 인식시켜줌
	public class Member {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@Column(name = "name", nullable = false)
	private String username;
	}
  • SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
    • @SequenceGenerator 필요
  • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
    • @TableGenerator 필요
  • AUTO: 방언에 따라 자동 지정, 기본값



권장하는 식별자 전략

기본 키 제약 조건: null 아님, 유일, 변하면 안된다.
• 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자.
• 예를 들어 주민등록번호도 기본 키로 적절하기 않다.
• 권장: Long형 + 대체키 + 키 생성전략 사용

profile
개발자

0개의 댓글