본문 바로가기
Back-End/자바 ORM 표준 JPA 프로그래밍

[JPA] 자바 ORM 표준 JPA 프로그래밍_4장

by ChaSso 2023. 5. 29.

4장 엔티티 매핑

∘ JPA를 사용할 때 엔티티와 테이블을 정확히 매핑하는 것이 중요

∘ JPA가 지원하는 매핑 어노테이션

  - 객체와 테이블 매핑 : @Enity, @Table

  - 기본 키 매핑 : @Id

  - 필드와 컬럼 매핑 : @Column

  - 연관관계 매핑 : @ManyToOne, @JoinColumn

 

 

4.1 @Entity

∘ JPA를 사용해서 테이블과 매핑할 클래스에 붙임

∘ JPA가 관리하는 엔티티

∘ 속성 : name

∘ 주의사항 

  - 기본 생성자가 있어야 됨 : JPA가 엔티티 객체를 생성할 때 기본 생성자를 사용하기 때문

  - final 클래스, enum, interface, inner 클래스에 사용할 수 없음

  - 저장할 필드에 final을 사용하면  안 됨

 

 

4.2 @Table

∘ 엔티티와 매핑할 테이블 지정

∘ 속성 : name, catalog, schema, uniqueConstraints(DDL)

 

 

4.3 다양한 매핑 사용

∘ 회원을 '일반 회원'과 '관리자'로 구분

   enum roleType으로 USERADMIN 구분,

      자바의 enum @Enumerated

∘ 회원 가입일과 수정일

  createdDate과 laseModifiedDate,

      자바의 날짜 타입 @Temporal

∘ 길이 제한이 없는 회원 설명 필드

   VARCHAR 대신 CLOB로 저장,

      @Lob로 CLOB, BLOB 매핑 가능

 

 

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

∘ JPA는 클래스의 매핑 정보와 데이터베이스 방언을 사용해서 데이터베이스 스키마를 자동으로 생성하는 기능을 지원함

∘  persistence.xml에 다음 코드를 추가 하면 애플리케이션 실행 시전에 데이터베이스 테이블을 자동으로 생성

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

∘ 다음 코드를 추가하면 콘솔에 실행되는 테이블 생성 DDL(Data Definicion Language)이 출력됨

<property name="hihbernate.show_sql" value="true" />

스키마 자동 생성 기능으로 만들어진 DDL은 운영 환경에서 사용할 만큼 완벽하지는 않기 때문에 참고만 하는 것이 좋음

∘ hibernate.hbm2ddl.auto 속성 : create, create-drop, update, validate, none

 

 

4.5 DDL 생성 기능

∘ @Column(nullable = false, length=10)

∘ @Table(uniqueConstraints = {@UniqueConstraint( ... )})

∘ 위 기능들은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않음

 

 

4.6 기본 키 매핑

∘ 애플리케이션에서 직접 기본 키를 할당하는 것이 아니라 데이터베이스가 생성해주는 값(ex. MySQL의 AUTO_INCREMEMT 가 생성하는 값)을 사용하는 방법

∘ JPA가 제공하는 데이터베이스 기본 키 생성 전략

  - 직접 할당 : 기본 키를 애플리케이션에서 직접 할당 (@Id 사용)

  - 자동 생성 : 대리 키 사용 방식 (@Id와 @GeneratedValue 사용)

    - IDENTITY, SEQUENCE, TABLE

 

4.6.1 기본 키 직접 할당 전략

∘ @Id 적용 가능 자바 타입 : 자바 기본형, 자바 Wrapper형, String, java.util.Date, java.sql.Date, java.math.BigDecimal, java.math.BigInteger

∘ 엔티티를 저장하기 전에 할당

 

4.6.2 IDENTITY 전략

∘ 기본 키 생성을 데이터베이스에 위임

∘ 

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

∘ JPA가 기본 키 값을 얻어오기 위해 데이터베이스를 추가로 조회

∘ em.persist() 엔티티를 데이터베이스에 저장 식별자 조회해서 엔티티의 식별자에 할당

 

4.6.3 SEQUENCE 전략

∘ 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트

∘ 시퀀스 생성 (BOARD_SEQ를 데이터베이스에 생성)

CREATE SEQUENCE BOARD_SEQ START WITH 1 INCREMENT BY 1;

∘ 시퀀스 생성기 등록 + 데이터베이스의 시퀀스와 매핑 + 시퀀스 생성기 선택

@Entity
@SequenceGenerator(
    name = "BOARD_SEQ_GENERATOR", //시퀀스 생성기 등록
    sequenceName = "BOARD_SEQ", //데이터베이스의 시퀀스와 매핑
    initialValue = 1, allocationSize = 1)
public class Board{
    @Id
    @GeneratedValue(strategy = GenerationTypr.SEQUENCE,
                    generator = "BOARD_SEQ_GENERATOR") //시퀀스 생성기 선택
    private Long id;
    ...
}

∘ em.persist() 호출 → 데이터베이스 시퀀스로 식별자 조회 → 조회한 식별자를 엔티티에 할당 → 엔티티를 영속성 컨텍스트에 저장 → 플러시 일어나면 엔티티를 데이터베이스에 저장   (IDENTITY와 순서 다름)

∘ @SequenceGenerator 속성 : name, sequenceName, initialValue, allocationSize, catalog, schema

 

4.6.4 TABLE 전략

∘ 키 생성 전용 테이블을 하나 만들고, 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략

∘ 모든 데이터베이스에 적용 가능

∘ 키 생성 용도의 테이블 생성

create table MY_SEQUENCES {
    sequence_name varchar(255) not null,
    next_val bigint,
    primary key ( sequence_name )
}

@Entity
@TableGenerator(
    name = "BOARD_SEQ_GENERATOR",
    table = "MY_SEQUENCES",  //테이블 키 생성기 등록
    pkColumnValue - "BOARD_SEQ", allocationSize = 1)
public class Board{
    @Id
    @GeneratedValue(strategy = GenerationTypr.TABLE,
                    generator = "BOARD_SEQ_GENERATOR") //테이블 키 생성기 지정
    private Long id;
    ...
}

∘ @TableGenerator 속성 : name, table, pkColumnName, valueColumnName, pkColumnValue, initialValue, allocationSize, catalog, schema, uniqueConstraints(DDL)

 

4.6.5 AUTO 전략

∘ 선택한 데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택

∘ 데이터베이스를 변경해도 코드를 수정할 필요가 없다는 것이 장점

 

4.6.6 기본 키 매핑 전략

∘ 영속성 컨텍스트는 엔티티를 식별자 값으로 구분하기 때문에 엔티티를 영속 상태로 만들려면 식별자 값이 반드시 있어야 함

∎ 직접 할당

SEQUENCE

TABLE

IDENTITY

 

 

4.7 필드와 컬럼 매핑: 레퍼런스

4.7.1 @Column

∘ 객체 필드를 테이블 컬럼에 매핑

∘ 속성 : 주로 name, nullable을 사용

 

4.7.2 @Enumerated

∘ 자바의 snum 타입을 매핑할 때 사용

∘ 다음처럼 사용

member.setRoleType(RoleType.ADMIN);

∘ EnumType.ORDINAL과 EnumType.STRING이 있는데 EnumType.STRING 사용을 권장

 

4.7.3 @Temporal

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

∘ 속성 : value (TemporalType.DATE, TemporalType.TIME, TemporalType.TIMESTAMP)

 

4.7.4 @Lob

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

∘ 속성 없음

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

 

4.7.5 @Trasnsient

∘ 객체에 임시로 어떤 값을 보관하고 싶을 때 사용

 

4.7.6 @Access

∘ JPA가 엔티티 데이터에 접근하는 방식 지정

필드 접근, 프로퍼티 접근

 

 

4.8 정리

∘ 데이터베이스 스키마 자동 생성하기 기능을 사용하면 엔티티 객체를 먼저 만들고 테이블은 자동으로 생성