Hello

Spring Data JPA Entity 연관관계

by 볼빵빵오춘기

연관관계를 사용함으로써 이점

더보기
  • 직관적인 관계 표현
    데이터베이스에서 테이블 간의 관계를 직접적으로 Entity 클래스에서 표현할 수 있다.
    @OneToMany, @ManyToOne, @OneToOne, @ManyToMany와 같은 어노테이션을 사용하여 엔티티 간의 관계를 명확하게 정의할 수 있다.
    이는 개발자가 코드만으로도 테이블 간의 관계를 이해하기 쉽게 만들어준다.

 

  • 자동화된 데이터 처리
    연관된 엔티티들을 함께 조회하거나 저장할 때, JPA는 자동으로 필요한 SQL 쿼리를 생성하고 실행한다.
    이를 통해 개발자는 복잡한 JOIN 쿼리나 매번 필요한 데이터를 수동으로 가져오는 작업에서 벗어날 수 있다.

 

  • 지연 로딩(Lazy Loading)
    연관된 엔티티들을 필요할 때만 가져올 수 있도록 지연 로딩을 지원한다.
    fetch = FetchType.LAZY를 설정하면 실제로 데이터가 필요할 때만 쿼리가 실행되어 성능을 최적화할 수 있다.
    반대로, FetchType.EAGER를 사용하면 연관된 모든 엔티티를 즉시 로딩하여 복잡한 쿼리를 단순화할 수도 있다.

 

  • 관계형 데이터베이스의 일관성 유지
    JPA를 사용하여 엔티티 간의 관계를 정의하면, 데이터베이스의 무결성과 일관성을 유지할 수 있다.
    부모 엔티티가 삭제될 때 연관된 자식 엔티티들을 자동으로 삭제하거나(cascade = CascadeType.REMOVE), 연관된 엔티티가 업데이트될 때 이를 자동으로 반영할 수 있다.

 

  • 단순하고 간결한 코드
    엔티티 간의 관계를 명시적으로 관리하기 때문에, 데이터베이스와의 상호작용에 필요한 코드가 줄어들고, 코드의 간결성 및 유지보수성이 크게 향상된다.

 

  • 복잡한 쿼리 작성 간소화
    엔티티 간의 관계가 정의되어 있으면, 복잡한 쿼리를 간단한 메소드 호출로 대체할 수 있다.
    특정 조건을 만족하는 엔티티들을 조회하거나 연관된 엔티티를 기반으로 데이터를 필터링하는 작업이 쉬워진다.

 

Entity간의 연관 관계

예시 코드1

// CommunityReplyEntity.java
@Entity
public class CommunityReplyEntity {

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

    private String replyContent;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="boardId")
    private CommunityEntity CBbs;

    // getters and setters
}

 

// CommunityEntity.java
@Entity
public class CommunityEntity {

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

    private String title;
    private String content;

    @OrderBy("id desc")
    @OneToMany(mappedBy = "CBbs", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
    private List<CommunityReplyEntity> reply;

    // getters and setters
}

 

코드 설명

  • CommunityEntity와 CommunityReplyEntity는 1:N 관계이다.
    하나의 CommunityEntity는 여러 개의 CommunityReplyEntity를 가질 수 있다.
  • CommunityReplyEntity에는 @ManyToOne 어노테이션이 사용되어 여러 개의 댓글이 하나의 게시글에 속한다는 것을 나타낸다.
  • CommunityEntity에는 @OneToMany 어노테이션이 사용되어 하나의 게시글에 여러 개의 댓글이 속할 수 있다는 것을 나타낸다.

 

어노테이션 설명

@JsonIgnore

  • @JsonIgnore는 Jackson 라이브러리에서 제공하는 어노테이션으로, JSON 직렬화/역직렬화 시 특정 필드를 무시하도록 한다.
  • 여기서는 CommunityReplyEntity의 CBbs 필드를 무시하도록 설정하여 순환 참조 문제를 방지한다.

 

@ManyToOne

  • @ManyToOne은 JPA의 어노테이션으로, CommunityReplyEntity에서 여러 댓글이 하나의 게시글에 속함을 나타낸다.
  • fetch = FetchType.EAGER는 관련 엔티티를 즉시 로드하도록 설정한다.
  • @JoinColumn(name = "boardId")는 외래 키 컬럼의 이름을 boardId로 지정한다.

 

@OneToMany

  • @OneToMany는 JPA의 어노테이션으로, CommunityEntity에서 하나의 게시글이 여러 댓글을 가질 수 있음을 나타낸다.
  • mappedBy = "CBbs"는 CommunityReplyEntity의 CBbs 필드가 연관 관계의 주인임을 나타낸다.
  • fetch = FetchType.EAGER는 관련 엔티티를 즉시 로드하도록 설정한다.
  • cascade = CascadeType.REMOVE는 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제되도록 설정한다.

 

@OrderBy

  • @OrderBy("id desc")는 댓글을 id 기준으로 내림차순 정렬하도록 한다.

예시 코드2

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

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id")
    private Address address;
    
    // .. 생략
}

 

@Entity
public class Address {
    @Id @GeneratedValue
    private Long id;
    
    private String city;
    private String street;

    @OneToOne(mappedBy = "address")
    private User user;
    
    // .. 생략
}

 

코드 설명

 

  • User 엔티티는 하나의 Address를 가질 수 있다.
    이 관계는 @OneToOne 어노테이션을 통해 정의다.
  • @JoinColumn(name = "address_id")는 User 테이블에서 Address 테이블의 외래 키를 나타내는 열을 지정한다.
  • Address 엔티티에서 mappedBy 속성을 사용하여 User 엔티티와의 양방향 관계를 정의한다.
    이로 인해 Address는 User에 의해 참조된다는 것을 나타낸다.
  • CascadeType.ALL은 User가 저장될 때 Address도 함께 저장되도록 한다.

 

 

어노테이션 설명

@OneToOne

두 엔티티가 1:1 관계를 가지는 경우에 사용된다.
예를 들어, 한 명의 사용자가 한 개의 주소를 가지는 상황을 생각해볼 수 있다.

 


 

예시코드3

@Entity
public class Student {
    @Id @GeneratedValue
    private Long id;
    
    private String name;

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

 

@Entity
public class Course {
    @Id @GeneratedValue
    private Long id;
    
    private String title;

    @ManyToMany(mappedBy = "courses")
    private List<Student> students = new ArrayList<>();
    
    // .. 생략
}

 

코드 설명

 

  • Student 엔티티와 Course 엔티티는 @ManyToMany 관계를 가진다.
  • @JoinTable은 다대다 관계에서 중간 테이블을 지정하기 위해 사용됩니다.
    이 예제에서는 student_course라는 이름의 테이블이 중간 테이블로 사용된다.
  • joinColumns는 Student 엔티티의 외래 키 열을 지정하고, inverseJoinColumns는 Course 엔티티의 외래 키 열을 지정한다.
  • mappedBy 속성을 사용하여 Course 엔티티가 Student에 의해 참조된다는 것을 나타낸다.

 

 

어노테이션 설명

@ManyToMany

두 엔티티가 다대다 관계를 가지는 경우에 사용된다.
예를 들어, 한 명의 학생이 여러 수업을 수강할 수 있으며, 한 개의 수업도 여러 학생에 의해 수강될 수 있는 상황을 생각해볼 수 있다.

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기