본문 바로가기

Spring/자바 ORM 표준 JPA 프로그래밍

04. 엔티티 매핑

💡 본 게시글은 김영한님의 인프런(Inflearn) 강의 자바 ORM 표준 JPA 프로그래밍 - 기본편에 대해 공부하고, 정리한 내용입니다.


1. 엔티티 매핑

JPA를 실무에 적용할 때 가장 중요한 부분 중 하나는 실제 객체와 RDB를 어떻게 매핑해서 사용하는지에 대한 이해입니다.

1) 엔티티 매핑 소개

  • 객체와 테이블 매핑: @Entity, @Table
  • 필드와 컬럼 매핑: @Column
  • 기본 키 매핑: @Id
  • 연관관계 매핑: @ManyToOne, @JoinColumn

(1) @Entity

  • @Entity가 붙은 클래스는 JPA가 관리하는 엔티티입니다.
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity가 필수입니다.
  • 주의사항:
    • 기본 생성자가 필수입니다(파라미터가 없는 public 또는 protected 생성자).
    • final 클래스, enum, interface, inner 클래스는 사용할 수 없습니다.
    • 저장할 필드에 final 사용 불가.

(2) @Entity 속성 정리

  • 속성: name
    • JPA에서 사용할 엔티티 이름을 지정합니다.
    • 기본값: 클래스 이름을 그대로 사용 (예: Member)
    • 같은 클래스 이름이 없으면 가급적 기본값을 사용합니다.
    • JPA가 구분하는 이름 정도로만 알아두면 됩니다.

(3) @Table

  • @Table은 엔티티와 매핑할 테이블을 지정합니다.
속성 기능 기본값
name 매핑할 테이블 이름 엔티티 이름을 사용
catalog 데이터베이스 catalog 매핑  
schema 데이터베이스 schema 매핑  
uniqueConstraints (DDL) DDL 생성 시에 유니크 제약 조건 생성  

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

  • DDL을 애플리케이션 실행 시점에 자동 생성합니다.
  • 테이블 중심 -> 객체 중심으로 전환합니다.
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL을 생성합니다.
    • 예: Oracle은 varchar2, MySQL은 varchar.
  • 이렇게 생성된 DDL은 개발 장비에서만 사용합니다.
    • 생성된 DDL은 운영 서버에서는 사용하지 않거나, 적절히 다듬은 후 사용해야 합니다.

(1) 데이터베이스 스키마 자동 생성 - 옵션

  • hibernate.hbm2ddl.auto 옵션:
옵션 설명
create 기존 테이블을 삭제하고 새로 생성합니다.
create-drop create와 같으나 종료 시점에 테이블도 삭제합니다.
update 변경분만 반영합니다.
validate 엔티티와 테이블이 정상 매핑되었는지만 확인합니다.
none 사용하지 않음.

(2) 데이터베이스 스키마 자동 생성 - 주의사항

  • 운영 장비에는 절대 create, create-drop, update를 사용하면 안 됩니다.
  • 개발 초기 단계create 또는 update를 사용합니다.
  • 개발 서버 또는 테스트 서버update 또는 validate를 사용합니다.
  • 스테이징과 운영 서버validate 또는 none을 사용합니다.
  • Note: 애플리케이션 로딩 시점에 자동으로 alter를 사용하는 것은 위험합니다. 스크립트를 직접 만들어서 테스트 서버에서 먼저 검증한 후 운영 서버에 반영하는 것이 좋습니다.

3) DDL 생성 기능

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

4) 요구사항 추가

  1. 회원은 일반 회원과 관리자로 구분해야 합니다.
  2. 회원 가입일과 수정일이 있어야 합니다.
  3. 회원을 설명할 수 있는 필드가 있어야 합니다. 이 필드는 길이 제한이 없습니다.

(1) 회원 엔티티 코드

package hellojpa;

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

@Entity
public class Member {

    @Id
    private Long id;

    @Column(name = "name")
    private String username;

    private Integer age;

    @Enumerated(EnumType.STRING)
    private RoleType roleType;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob
    private String description;

    public Member() { 
        // JPA는 객체를 생성해서 reflection을 활용하여 값을 동적으로 채워주기에 기본 생성자가 필수로 필요하다.
    }
}

(2) 필드 설명

  • @Column(name = "name"): 객체는 username으로 사용하고, DB 필드명은 name으로 사용하고 싶을 때 사용합니다.
  • @Enumerated(EnumType.STRING): DB에는 enum 타입이 없기 때문에 String 값으로 저장합니다.
  • @Temporal(TemporalType.TIMESTAMP): 날짜 타입 매핑에 사용됩니다.
  • @Lob: DB에 varchar를 넘어서는 큰 콘텐츠를 넣을 때 사용합니다.

5) 매핑 어노테이션 정리

(1) @Column

  • insertable, updatable: 해당 컬럼이 insert되거나 update 가능 여부를 지정합니다.
  • unique: 제약 조건명을 지정할 수 없기 때문에 잘 사용하지 않습니다.

(2) @Enumerated

  • 자바 enum 타입을 매핑할 때 사용합니다.
  • 속성: value (기본 값: EnumType.ORDINAL)
    • EnumType.ORDINAL: enum 순서를 데이터베이스에 저장합니다. (주의: 운영에서 사용하지 않음)
    • EnumType.STRING: enum 이름을 데이터베이스에 저장합니다.

(3) @Temporal

  • 날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용합니다.
  • 참고: LocalDate, LocalDateTime을 사용할 때는 생략 가능.

(4) @Lob

  • 데이터베이스 BLOB, CLOB 타입과 매핑합니다.
  • 매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑입니다.

6) 기본 키 매핑 어노테이션

  • @Id
  • @GeneratedValue
@Entity
class Product {
  @Id 
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
}

7) 기본 키 매핑 방법

  1. 직접 할당: @Id만 사용
  2. 자동 생성(@GeneratedValue)
    • IDENTITY: 데이터베이스에 위임, MySQL
    • SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, Oracle
      @SequenceGenerator 필요
    • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
      @TableGenerator 필요
    • AUTO: 방언에 따라 자동 지정, 기본값

(1) IDENTITY 전략 - 특징

  • 기본 키 생성을 데이터베이스에 위임합니다.
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용됩니다.
  • 단점: 모아서 INSERT가 불가능합니다.

(2) SEQUENCE 전략 - 특징

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트입니다.
  • JPA가 persist()를 호출할 때 시퀀스를 먼저 조회하여 엔티티에 세팅하고, 커밋 시점에 버퍼에 쌓인 쿼리를 한 번에 실행합니다.
@Entity
@SequenceGenerator(
  name = "MEMBER_SEQ_GENERATOR",
  sequenceName = "MEMBER_SEQ", 
  initialValue = 1, 
  allocation

Size = 50)
public class Member {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
  private Long id;
}

(3) TABLE 전략

  • 키 생성 전용 테이블을 만들어서 데이터베이스 시퀀스를 흉내내는 전략입니다.
  • 장점: 모든 데이터베이스에 적용 가능합니다.
  • 단점: 성능이 저하될 수 있습니다.
@Entity
@TableGenerator(
  name = "MEMBER_SEQ_GENERATOR",
  table = "MY_SEQUENCES",
  pkColumnValue = "MEMBER_SEQ", 
  allocationSize = 1)
public class Member {
  @Id
  @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
  private Long id;
}

8) 권장하는 식별자 전략

  • 기본 키 제약 조건: null 아님, 유일, 변하면 안 됨.
  • 대리 키(대체 키)를 사용합니다.
  • 권장: Long형 + 대체 키 + 키 생성 전략 사용.

9. 총 정리

  1. 엔티티 매핑의 중요성
    • JPA를 실무에 적용할 때 객체와 RDB를 매핑하는 방법은 매우 중요하며, 이를 이해하고 활용하는 것이 필요합니다.
  2. 엔티티 및 필드 매핑 어노테이션 이해
    • @Entity, @Table, @Column 등의 매핑 어노테이션을 통해 객체와 테이블을 매핑하고, 다양한 필드 속성을 제어할 수 있습니다.
  3. 데이터베이스 스키마 자동 생성
    • 개발 환경에서 편리하게 사용될 수 있지만, 운영 환경에서는 매우 주의해야 합니다. 운영 환경에서는 validate 또는 none을 권장합니다.
  4. 기본 키 매핑 전략
    • IDENTITY, SEQUENCE, TABLE 전략 중 상황에 맞게 적절한 전략을 선택하고, 성능 최적화를 위해 allocationSize를 설정할 수 있습니다.
  5. 기본 키와 대리 키 사용 권장
    • 자연 키보다는 변하지 않는 대리 키를 사용하는 것이 좋으며, Long 타입의 식별자를 권장합니다.
  6. 유연한 매핑과 제약 조건 설정
    • @Column, @Enumerated, @Lob 등을 사용해 다양한 매핑 요구사항을 충족할 수 있습니다.

위 내용을 바탕으로 JPA의 엔티티 매핑과 데이터베이스 스키마 관리에 대한 이해를 높이고, 실무에 적합한 전략을 선택할 수 있는 능력을 키울 수 있습니다.

'Spring > 자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글

06. 다양한 연관관계 매핑  (1) 2024.09.08
05. 연관관계 매핑 기초  (0) 2024.09.08
03. 영속성 관리 - 내부 동작 방식  (0) 2024.08.11
02. JPA 시작하기  (0) 2024.08.11
01. JPA 소개  (0) 2024.07.24