백엔드 프레임워크/JPA & Mybatis

[JPA] 엔티티 매핑 (Entity Mapping)

ioh'sDeveloper 2025. 1. 11. 17:25

엔티티 매핑 (Entity Mapping)

엔티티 매핑(Entity Mapping)은 객체 지향 프로그래밍에서 엔티티 클래스와 데이터베이스 테이블 간의 매핑을 정의하는 핵심 개념입니다. JPA(Java Persistence API)와 같은 ORM(Object-Relational Mapping) 기술을 활용하여 데이터베이스와 객체 간의 데이터를 매핑하고 관리할 수 있습니다. 이번 글에서는 엔티티 매핑의 기본 개념, 주요 애노테이션, 실무 적용 사례, 그리고 엔티티 매핑 시 주의해야 할 점에 대해 다뤄보겠습니다.


1. 엔티티 매핑의 기본 개념

엔티티(Entity)는 데이터베이스의 테이블과 매핑되는 자바 클래스입니다. JPA를 통해 우리는 자바 객체를 데이터베이스 테이블에 쉽게 매핑하고, CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있습니다.

엔티티 클래스는 반드시 다음 조건을 만족해야 합니다:

  • @Entity 애노테이션이 클래스에 선언되어 있어야 함
  • 기본 생성자를 포함해야 함
  • 식별자가 필요하며, 주로 @Id 애노테이션을 사용해 설정함

2. 주요 JPA 애노테이션

엔티티 매핑 시 사용하는 주요 애노테이션은 다음과 같습니다.

2.1 @Entity

@Entity는 클래스가 엔티티임을 선언하는 애노테이션입니다. 데이터베이스 테이블과 매핑되는 클래스를 정의할 때 사용됩니다.

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
}

2.2 @Table

@Table 애노테이션은 엔티티가 매핑될 데이터베이스 테이블의 이름을 명시적으로 지정할 때 사용합니다.

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
}

2.3 @Id와 @GeneratedValue

@Id는 테이블의 기본 키(primary key)를 지정하는 애노테이션이며, @GeneratedValue는 키 생성 전략을 설정합니다.

import jakarta.persistence.*;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private Double price;
}

2.4 @Column

@Column은 테이블의 컬럼과 엔티티 필드를 매핑할 때 사용합니다. 컬럼의 이름, 길이, nullable 여부 등을 설정할 수 있습니다.

import jakarta.persistence.*;

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "customer_name", length = 50, nullable = false)
    private String name;

    @Column(name = "customer_email", unique = true)
    private String email;
}

3. 실무 적용 사례

3.1 단방향 매핑

단방향 매핑은 한 엔티티에서 다른 엔티티로의 참조를 갖는 구조입니다.

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;
}

3.2 양방향 매핑

양방향 매핑은 두 엔티티가 서로 참조를 갖는 구조입니다.

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "customer")
    private List<Order> orders = new ArrayList<>();
}

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;
}

4. 엔티티 매핑 시 주의사항

4.1 Lazy Loading과 Eager Loading

  • Lazy Loading: 실제로 데이터를 사용할 때 로드됨
  • Eager Loading: 엔티티를 조회할 때 즉시 로드됨

실무에서는 성능 최적화를 위해 대체로 Lazy Loading을 권장합니다.

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "employee", fetch = FetchType.LAZY)
    private List<Task> tasks;
}

4.2 연관관계 매핑 시 고려사항

  • 연관관계의 주인은 반드시 @JoinColumn을 사용해야 함
  • 양방향 매핑 시 무한 루프를 방지하기 위해 toString(), equals(), hashCode()를 조심히 사용해야 함

5. 결론

엔티티 매핑은 JPA와 같은 ORM 기술의 핵심입니다. 올바른 엔티티 매핑을 통해 우리는 데이터베이스와의 상호작용을 효율적으로 관리할 수 있으며, 코드의 유지보수성과 확장성을 높일 수 있습니다. 이번 글에서 소개한 주요 개념과 실무 사례를 통해 엔티티 매핑을 보다 효과적으로 활용할 수 있기를 바랍니다.