개발천재

[Spring Boot] JPA 매핑 어노테이션 정리 본문

개발 준비/Spring Boot

[Spring Boot] JPA 매핑 어노테이션 정리

세리블리 2025. 2. 27. 23:35
반응형

데이터베이스에서 테이블 간의 관계를 올바르게 설정하는 것은 애플리케이션의 데이터 무결성과 성능을 유지하는 데 중요한 요소이다. JPA에서는 이러한 관계를 보다 직관적이고 효율적으로 관리할 수 있도록 @ManyToOne, @OneToMany, @OneToOne, @ManyToMany와 같은 매핑 어노테이션을 제공한다.

 


 

 

@ManyToOne (다대일 관계)

여러 개의 자식이 하나의 부모에 속한다.

 

@ManyToOne은 다대일(N:1) 관계를 매핑할 때 사용하는 JPA 어노테이션으로, 여러 개의 엔티티가 하나의 엔티티를 참조하는 구조를 의미한다. 예를 들어, 여러 개의 주문(Order)이 하나의 회원(User)에 속하는 경우, Order 엔티티에서 User 엔티티를 @ManyToOne으로 매핑할 수 있다.

 

이때, 외래 키(FK)는 다(N) 쪽의 테이블에 저장되며, @JoinColumn(name = "user_id")을 사용하여 데이터베이스 컬럼과 매핑할 수 있다.

 

@ManyToOne 관계는 기본적으로 즉시 로딩(EAGER) 방식이므로, 성능 최적화를 위해 필요에 따라 지연 로딩(LAZY) 설정을 추가하는 것이 좋다.


아래의 코드는 회원과 주문 관계를 표현한 예제이다. 한 명의 회원(User)은 여러 개의 주문(Order)을 할 수 있다.

  • @ManyToOne는 주문(Order) 여러 개가 한 명의 회원(User)에 속하는 것을 말한다.
  • @JoinColumn(name = "user_id")은 외래 키(FK)를 설정하여 user_id 컬럼을 참조하는 것을 말한다.
@Entity
public class Order {
    
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id") // 외래 키 설정 (FK)
    private User user;

    // Getter, Setter 생략
}

 

 


 

@OneToMany (일대다 관계)

하나의 부모(일)에 여러 개의 자식(다)이 속한다.

 

@OneToMany는 일대다(1:N) 관계를 매핑할 때 사용하는 JPA 어노테이션으로, 하나의 엔티티가 여러 개의 엔티티를 가질 수 있는 구조를 의미한다. 예를 들어, 회원(User) 한 명이 여러 개의 주문(Order)을 할 수 있는 경우, User 엔티티에서 @OneToMany(mappedBy = "user")로 Order 엔티티와 관계를 맺을 수 있다.

 

여기서 mappedBy 속성은 연관 관계의 주인이 아님을 나타내며, 외래 키(FK)는 Order 엔티티에 저장된다.

 

@OneToMany는 기본적으로 지연 로딩(LAZY) 방식이므로, 필요한 시점에 데이터를 불러오는 것이 가능하며, 성능 최적화를 위해 CascadeType 옵션을 활용할 수도 있다.


아래의 코드는 회원(User) 한 명이 여러 개의 주문(Order)을 할 수 있는 구조의 엔티티이다.

  • @OneToMany(mappedBy = "user")은 주문(Order) 엔티티의 user 필드와 연결되어 있다는 것을 말한다.
  • mappedBy를 사용하면 User 엔티티에는 외래 키가 생성되지 않는다(주 테이블의 FK는 Order에 있음).
@Entity
public class User {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "user") // Order 엔티티의 user 필드와 매핑
    private List<Order> orders = new ArrayList<>();

    // Getter, Setter 생략
}

 

 


 

 

@OneToOne (일대일 관계)

한 개의 데이터가 다른 하나와 1:1로 연결된다.

 

@OneToOne은 일대일(1:1) 관계를 매핑할 때 사용하는 JPA 어노테이션으로, 한 개의 엔티티가 다른 하나의 엔티티와 1:1로 연결되는 구조를 의미한다. 예를 들어, 회원(User) 한 명이 하나의 주소(Address) 정보를 가질 경우, User 엔티티에서 @OneToOne을 사용하여 Address 엔티티와 관계를 맺을 수 있다.

 

이때, @JoinColumn(name = "user_id")을 설정하면 외래 키(FK)가 해당 엔티티 테이블에 저장되며, 어느 쪽에 FK를 둘지는 설계에 따라 결정할 수 있다. 기본적으로 즉시 로딩(EAGER) 방식이므로, 성능 최적화를 위해 fetch = FetchType.LAZY를 지정하는 것이 권장된다.

 

아래의 코드의 예시는 회원과 주소 관계에 관한 엔티티이다.  회원(User) 한 명당 하나의 주소(Address)만 가질 수 있다.

  • @OneToOne은 1:1 관계를 정의한 것이다.
  • @JoinColumn(name = "user_id")은 외래 키를 user_id로 설정하여 User와 연결한 것이다.
@Entity
public class Address {
    
    @Id @GeneratedValue
    private Long id;

    @OneToOne
    @JoinColumn(name = "user_id") // 외래 키 설정 (FK)
    private User user;

    // Getter, Setter 생략
}

 

 


 

 

@ManyToMany (다대다 관계)

여러 개의 데이터가 여러 개와 연결된다.

 

@ManyToMany는 다대다(N:M) 관계를 매핑할 때 사용하는 JPA 어노테이션으로, 여러 개의 엔티티가 서로 다수의 엔티티와 연결되는 구조를 의미한다. 예를 들어, 학생(Student) 한 명이 여러 개의 수업(Course)을 들을 수 있고, 반대로 하나의 수업(Course)에 여러 명의 학생(Student)이 등록될 수 있는 경우, @ManyToMany를 사용하여 관계를 설정할 수 있다.

 

다대다 관계는 중간 테이블이 필요하기 때문에 @JoinTable(name = "student_course")을 사용하여 연결 테이블을 명시적으로 지정해야 한다. 기본적으로 즉시 로딩(EAGER) 방식이며, 성능 최적화를 위해 fetch = FetchType.LAZY 설정을 고려하는 것이 좋다.

 

다만, 다대다 관계는 실무에서 자주 사용되지 않으며, 중간 엔티티(예: Enrollment 같은 연결 테이블)를 생성하여 1:N, N:1 관계로 풀어내는 방식이 일반적이다.

 

아래의 코드는 학생(Student) 여러 명이 여러 개의 수업(Course)을 들을 수 있는 엔티티이다.

  • @ManyToMany로 다대다 관계를 정의한다.
  • @JoinTable로 중간 테이블(student_course)을 생성하여 다대다 관계를 해결한다.
  • joinColumns = @JoinColumn(name = "student_id")은 Student의 FK이다.
  • inverseJoinColumns = @JoinColumn(name = "course_id")은 Course의 FK이다.
@Entity
public class Student {

    @Id @GeneratedValue
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List<Course> courses = new ArrayList<>();
}

 

 


 

매핑 어노테이션 정리

어노테이션 관계 설명 예제
@ManyToOne 다대일 여러 개의 자식이 하나의 부모에 속함 주문(Order) → 회원(User)
@OneToMany 일대다  하나의 부모가 여러 개의 자식을 가짐 회원(User) → 주문(Order)
@OneToOne 일대일 하나의 데이터가 하나와 1:1 연결됨 회원(User) → 주소(Address)
@ManyToMany 다대다 여러 개가 여러 개와 연결됨 (중간 테이블 필요) 학생(Student) ↔ 수업(Course)
반응형