[JPA 기본] 엔티티 매핑 👨‍💻

홍정완·2022년 10월 28일
0

JPA

목록 보기
31/38
post-thumbnail
post-custom-banner

객체와 테이블 매핑


@Entity

  • @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다.

  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수

  • 주의사항
    a. 기본 생성자 필수 (파라미터가 없는 public or protected)
    b. final 클래스를 enum, interface inner 클래스에 사용 ❌
    c. 저장할 필드에 final 사용 ❌
  • 속성 : name
    a. JPA에서 사용할 엔티티 이름 지정.
    b. 기본값 클래스 이름을 그대로 사용 (예 : Member)
    c. 같은 클래스 이름이 없으면 가급적 기본값을 사용한다.

@Table

  • @Table은 엔티티와 매핑할 테이블 지정



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


  • DDL을 애플리케이션 실행 시점에 자동 생성
  • 테이블 중심 → 객체 중심
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용



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



주의 사항

  • 운영 장비에는 절대 create, create-drop, update 사용하면 안 된다.
  • 개발 초기 : create or update
  • 테스트 서버 : update or validate
  • 스테이징과 운영서버 : validate or none



필드와 컬럼 매핑


package hellojpa;

import javax.persistence.*;
import java.time.LocalDate;
import java.util.Date;

@Entity
public class Member2 {
    
    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    private String username;
    
    @Enumerated(EnumType.STRING)
    private RoleType roleType;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date cereatedDate;
    
    private LocalDate lastModifiedDate;
    
    @Lob
    private String description;

		@Transient
		private int tmp_number;
}



매핑 어노테이션 정리



@Column



@Enumerated - ORDINAL 사용 ❌



@Temporal

  • 날짜 타입 java.util.Date, java.util.Calendar을 매핑할 때 사용

✅ LocalDate, LocalDateTime을 사용할 때는 생략 가능 (최신 하이버네이트 지원)



@Lob

  • 데이터베이스 BLOB, CLOB 타입과 매핑

    • @Lob에는 지정할 수 있는 속성이 없다.

    • 매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑

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

CLOB(Character Large Object)

  • 데이터베이스 관리 시스템에 쓰이는 문자 데이터의 모임

BLOB(Binary Large Object)

  • 데이터베이스 관리 시스템의 하나의 엔티티로서 저장되는 이진 데이터의 모임



@Transient

  • 필드 매핑 ❌
  • 데이터베이스에 저장 ❌, 조회 ❌
  • 주로 메모리상에서만 임시로 어떤 값을 보관하고 싶을 때 사용
@Transient
private Integer temp;



기본 키 매핑


  • 직접 할당 : @Id만 사용

  • 자동 생성 (@GeneratedValue)

    • IDENTITY : 데이터베이스에 위임, MYSQL
    • SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE, @SequenceGenerator 필요
    • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용, @TableGenerator 필요
    • AUTO : 방언에 따라 자동 지정, 기본값



SEQUENCE - @SequenceGenerator


@Entity
@SequenceGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        sequenceName = "MEMBER_SEQ",
        initialValue = 1
)
public class Member2 {
		@Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
    @Column(name = "MEMBER_ID")
    private Long id;
	...
}



Table 전략

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내 내는 전략
  • 모든 데이터 베이스에서 사용할 수 있지만, 성능이 떨어진다.

@TableGenerator - 속성


@Entity
@TableGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        table = "MY_SEQUENCES",
        pkColumnName = "MEMBER_SEQ", allocationSize = 1)
public class Member2 {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
    @Column(name = "MEMBER_ID")
    private Long id;
...
}



권장하는 식별자 전략

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



실전 예제 - 요구사항 분석과 기본 매핑


요구사항 분석

  • 회원은 상품을 주문할 수 있다.
  • 주문 시 여러 종류의 상품을 선택할 수 있다.



기능 목록

  • 회원 기능

    • 회원 등록
    • 회원 조회
  • 상품 기능

    • 상품 등록
    • 상품 수정
    • 상품 조회
  • 주문 기능

    • 상품 주문
    • 주문내역 조회
    • 주문취소



도메인 모델 분석

  • 회원과 주문의 관계 : 회원은 여러 번 주문할 수 있다. → 일대다 관계(1:N)
  • 주문과 상품의 관계 : 주문 시 여러 상품을 선택할 수 있다. 반대로 상품도 여러 번 주문될 수 있다.
    → 다대다 관계(N:M)
    → 주문 상품(OrderItem)이라는 모델을 만들어서 일대다(1:N), 다대일(N:1) 관계로 풀어낸다.



테이블 설계



엔티티 설계와 매핑



✅ 데이터 중심 설계의 문제점

  1. 현재 방식은 객체 설계를 테이블 설계에 맞춘 방식
  2. 테이블의 외래 키를 객체에 그대로 가져옴
  3. 객체 그래프 탐색이 불가능
  4. 참조가 없으므로 UML도 잘못됨
profile
습관이 전부다.
post-custom-banner

0개의 댓글