TIL - 20251011

juni·2025년 10월 10일

TIL

목록 보기
150/316

1011 Spring Boot & JPA: 엔티티와 연관관계 매핑 복습


✅ 1. 엔티티(Entity)의 기본 개념

  • 엔티티(Entity)란 데이터베이스의 테이블과 직접적으로 매핑되는 Java 객체입니다. JPA는 이 엔티티 객체의 변화를 감지하여, 데이터베이스에 자동으로 SQL을 실행해주는 역할을 합니다.

➕ 엔티티를 위한 필수 어노테이션

  1. @Entity:

    • 이 클래스가 JPA가 관리하는 엔티티임을 선언합니다.
    • JPA는 이 어노테이션이 붙은 클래스를 찾아 데이터베이스 테이블과 연결합니다.
  2. @Table:

    • 엔티티와 매핑될 테이블의 세부 정보를 지정합니다. (선택 사항)
    • 주로 클래스 이름과 테이블 이름을 다르게 하고 싶을 때 사용합니다. (e.g., name = "users")
  3. @Id:

    • 테이블의 기본 키(Primary Key, PK)에 해당하는 필드임을 나타냅니다. 모든 엔티티는 @Id 필드를 반드시 가져야 합니다.
  4. @GeneratedValue:

    • 기본 키의 값을 자동으로 생성하는 전략을 지정합니다.
    • strategy = GenerationType.IDENTITY: 데이터베이스(e.g., MySQL의 AUTO_INCREMENT)에 기본 키 생성을 위임하는 방식으로, 가장 널리 사용됩니다.
  5. @Column:

    • 필드와 매핑될 테이블의 컬럼에 대한 세부 설정을 지정합니다. (선택 사항)
    • name, nullable, unique, length 등의 속성을 통해 제약조건을 설정할 수 있습니다.

➕ 간단한 User 엔티티 예시

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", nullable = false, unique = true, length = 50)
    private String username;

    @Column(nullable = false)
    private String password;

    // ... Getters and Setters ...
}

✅ 2. 연관관계 매핑의 핵심

  • 객체지향 프로그래밍에서는 객체 간의 참조를 통해 관계를 표현하지만, 관계형 데이터베이스는 외래 키(Foreign Key, FK)를 통해 관계를 표현합니다. 연관관계 매핑은 이 둘 사이의 패러다임 불일치를 해결하여, 개발자가 SQL이 아닌 객체 중심으로 관계를 다룰 수 있게 해주는 JPA의 핵심 기능입니다.

➕ 연관관계 매핑 시 고려해야 할 3가지 요소

  1. 방향 (Direction): 단방향, 양방향

    • 단방향: 한쪽 엔티티만 다른 엔티티를 참조하는 관계. (e.g., PostUser)
    • 양방향: 양쪽 엔티티가 서로를 참조하는 관계. (e.g., PostUser)
  2. 다중성 (Multiplicity): 일대일, 일대다, 다대일, 다대다

    • @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
  3. 연관관계의 주인 (Owner):

    • 양방향 관계에서만 존재하는 개념으로, 두 엔티티 중 누가 외래 키(FK)를 관리할지를 결정합니다.
    • 주인이 아닌 쪽mappedBy 속성을 사용하여 "나는 주인이 아니며, 주인의 이 필드에 의해 매핑되었다"고 명시해야 합니다.
    • 규칙: 외래 키가 있는 곳을 주인으로 정하는 것이 일반적입니다. 즉, N(다) 쪽이 주인이 됩니다.

✅ 3. 다중성별 매핑 전략

➕ 3-1. @ManyToOne (다대일) - 가장 중요하고 흔한 관계

  • 설명: 여러 개의 Post가 하나의 User에 속하는 관계.

  • 구현: Post 엔티티가 User를 참조하며, post 테이블에 user_id (FK)가 생성됩니다. N쪽인 Post가 연관관계의 주인이 됩니다.

    // Post.java (N쪽, 연관관계의 주인)
    @ManyToOne
    @JoinColumn(name = "user_id") // 생성될 FK 컬럼 이름 지정
    private User user;
    
    // User.java (1쪽, 주인이 아님)
    @OneToMany(mappedBy = "user") // Post 엔티티의 'user' 필드에 의해 매핑됨
    private List<Post> posts = new ArrayList<>();

➕ 3-2. @OneToMany (일대다)

  • @ManyToOne의 반대 방향. 보통 @ManyToOne과 함께 양방향 관계를 구성하는 데 사용됩니다.

➕ 3-3. @OneToOne (일대일)

  • 설명: UserUserProfile처럼 하나의 엔티티가 다른 엔티티와 1:1로만 관계를 맺는 경우.
  • 구현: 외래 키를 어느 테이블에 둘지에 따라 주인을 정합니다. 주로 더 자주 조회되는 쪽에 FK를 두는 것이 성능상 유리합니다.

➕ 3-4. @ManyToMany (다대다)

  • 설명: PostTag처럼, 하나의 게시글에 여러 태그가, 하나의 태그가 여러 게시글에 속할 수 있는 관계.
  • 문제점: 관계형 데이터베이스는 다대다 관계를 직접 표현할 수 없어, 두 테이블을 연결하는 중간 테이블(연결 테이블)이 반드시 필요합니다.
  • JPA 구현: @ManyToMany@JoinTable 어노테이션을 사용하면 JPA가 자동으로 중간 테이블을 생성하고 관리해줍니다.
  • 실무적 조언: 실무에서는 중간 테이블에 추가적인 정보(e.g., 등록일)가 들어가는 경우가 많아, @ManyToMany를 직접 사용하기보다는, 중간 테이블에 해당하는 연결 엔티티(PostTag)를 직접 만들고, 이를 @ManyToOne + @OneToMany 관계로 풀어내는 "다대다 관계 해소" 방식을 더 선호합니다.

📌 요약

  • @Entity는 DB 테이블과 매핑되는 Java 객체를 의미하며, @Id@GeneratedValue로 기본 키를 설정합니다.
  • 연관관계 매핑은 객체의 참조와 DB의 외래 키(FK) 사이의 간극을 메워주는 JPA의 핵심 기능입니다.
  • 매핑 시에는 방향, 다중성, 연관관계의 주인이라는 3가지 요소를 반드시 고려해야 합니다.
  • N(다) 쪽이 외래 키를 가지므로, @ManyToOne이 붙은 쪽이 연관관계의 주인이 되는 것이 가장 일반적이고 중요한 패턴입니다.
  • @ManyToMany는 실무에서 중간 테이블에 추가 데이터가 필요할 경우, 별도의 연결 엔티티를 만들어 풀어내는 것이 더 유연한 설계입니다.

0개의 댓글