Java & Spring/JPA

[Spring] JPA 2

nippycloud 2026. 1. 28. 21:39

ORM : Object Relation Mapping

JPA의 가장 큰 특징 중 하나는 ORM 기술이라는 것이다.

JPA는 Java의 객체와 DataBase의 관계 위에 세워져있는 기술이다.

 

<JPA의 객체 - 관계 매핑>

@Entity, @Table : 객체 & 테이블 지정 방법

@Id : DB에서 PK 지정 방법

@Column : Java 필드와 DB 컬럼 매핑 방법

@ManyToOne, @JoinColumn : DB의 N:1 등 연관관계를 Java에 매핑하는 방법

 

1. @Entity, @Table

@Getter
@Entity 
@Table(name = "orders") 
public class Order extends BaseEntity {
    @Id @GeneratedValue 
    @Column(name = "orders_id")
    private Long id;

    @Enumerated(EnumType.STRING)
    private OrderStatus status; 
}

 

위 예시에서 @Table은 Order 클래스처럼 DB에서 클래스 이름을 그대로 사용할 수 없을 때 테이블의 이름을 개발자가 직접 지정해주기 위해 사용한다. (DB에서 Order은 Order by .... 가 있기 때문에 사용 불가)

일반적으로 @Table은 생략할 수 있다.

(생략 시 @Entity Class Member { ... } : DB에 member 테이블로 등록, 소문자 & 스네이크 표기)

 

@Entity

- 해당 클래스를 JPA에서 관리하는 엔티티로 지정 

- 지정한 클래스는 DB 테이블로 등록, 매핑되며 JPA의 영속성 컨텍스트에 의해 생명 주기가 관리된다. (영속화, 준영속, 비영속 ..)

- @Entity 사용 시 해당 클래스는 반드시 기본 생성자를 가져야 한다.

- @NoArgsConstructor(access = AccessLevel.PROTECTED)) or @NoArgsConstruct or 다른 생성자가 없을 경우 기본 생성자는 지정하지 않아도 Java 문법에 의해 자동으로 등록된다.

 

 

@Table 

- 생략 가능, 생략 시 현재 클래스 이름을 DB 테이블 이름으로 설정하여 테이블 생성 (소문자, 스네이크 표기)

- @Table (name = "...") 로 지정 시 현재 클래스의 이름이 지정된 이름으로 DB 테이블에 등록된다.

- @Table(
    uniqueConstraints = {
        @UniqueConstraint(name = "uk_email", columnNames = "email")
    }
)

 

  • name = "uk_email" → DB에 생성될 제약조건 이름을 uk_email로 지정
  • columnNames = "email" → 제약조건을 적용할 컬럼 이름 지정

 

 

2. @Id, @GeneratedValue, @Column

@Id @GeneratedValue 
@Column(name = "orders_id")
private Long id;

 

@Id : 해당 필드를 DB의 PK로 등록한다.

@GeneratedValue : 등록한 PK에 대해 데이터가 들어갈 때마다 DB 레벨에서 Auto Increment를 수행한다. (PK 자동 증가)

@Column : 생략 가능하며, DB에 필드명 그대로 컬럼으로 등록하지 않고 개발자가 직접 컬럼 이름을 지정하고 싶을 때 name과 함께 사용한다. 생략 시 필드 이름이 그대로 DB 컬럼 명으로 설정된다. (소문자 & 스네이크 표기) 다른 테이블과 컬럼명이 겹치지 않게 하기 위해 사용한다.

 

// @Id만 사용하고 @GeneratedValue를 사용하지 않을 경우
Board board = new Board();
board.setId(1); // 직접 pk를 애플리케이션에서 설정해야 한다.

 

// @Id, @GeneratedValue를 함께 사용 시
Board board = new Board();
em.persist(board);

System.out.println(board.getId()); // pk가 DB에서 자동 생성, 할당되어 정상 출력

 

영속화되기 위해서는 PK가 반드시 필요하다.
em.persist() : 쓰기 지연이 동작하지 않고 즉시 insert 쿼리가 실행
DB에 저장 후 pk 할당한 엔티티 리턴 : 쓰기 지연이 동작하지 않기에 pk를 가진 엔티티가 영속화될 수 있다.

 

3. @Enumerated

@Enumerated(EnumType.STRING)
private OrderStatus status; // 주문 상태 : ORDER, CANCEL

 

@Enumerated : Java의 enum 타입을 DB 컬럼으로 저장할 때 사용

Java Enum -> DB Varchar 저장 (EnumType.STRING)

Java Enum -> DB INT 저장 (EnumType.ORDINAL) 

- DB에서도 Enum으로 저장되는 것이 아니다.

 

public enum OrderStatus {
    ORDER, CANCEL
}

 

@Enumerated(EnumType.ORDINAL) : enum 순서를 숫자(0,1,2...)로 저장

@Enumerated(EnumType.STRING) : enum 이름 자체를 문자열로 저장 => 실무에서 기본적으로 사용하도록 권장

 

해당 부분을 확인하면 JPA는 아래와 같은 SQL을 데이터베이스에 전달한다. 

CREATE TABLE `orders` (
  ... 
  `status` VARCHAR(255)
);

 

 

@Enumerated(EnumType.STRING)

id : status

1  : ORDER

2. : CANCEL

위와 같은 방식으로 데이터베이스에 VARCHAR 타입으로 저장된다. (ENUM 타입이 아님, MySQL 등 여러 DB에 같은 원리로 저장)

@Enumerated(EnumType.ORDINAL) : STRING과 다르게 데이터베이스에 INT 타입으로 저장

 

 

'Java & Spring > JPA' 카테고리의 다른 글

[Spring] JPA 5  (1) 2026.03.03
[Spring] JPA 변경 감지  (0) 2026.02.13
[Spring] JPA 4  (0) 2026.02.12
[Spring] JPA 3  (0) 2026.02.05
[Spring] JPA 1  (0) 2026.01.20