Yebali

Spring JPA 1:N 관계 설정 본문

Spring

Spring JPA 1:N 관계 설정

예발이 2021. 10. 10. 22:26

Spring JPA의 다양한 관계 매핑 중 1:N 관계를 설정하는 간단한 예시이다.

예시 테이블

위의 테이블은 우리가 작성하는 tistory의 게시글을 간단하게 표현한 테이블이다.
tbl_post: 게시글의 id(PK), 제목, 내용으로 구성되어있다.
tbl_hashtag: 해시태그의 id(PK), 해시태그가 속한 게시글의 id(FK), 해시태그 값으로 구성되어있다.

 

Post Entity

@Entity
@Getter @Setter
@Table(name = "tbl_post")
public class Post {

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

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private List<HashTag> hashTags = new ArrayList<>();

    private String title;

    private String content;

    //==연간관계 매서드==//
    public void addHashTag(HashTag hashTag) {
        this.hashTags.add(hashTag);
        hashTag.setPost(this);
    }

    public static Post createPost(String product, String title, String content, HashTag... hashTags) {
        Post post = new Post();
        post.setTitle(title);
        post.setContent(content);
        for (HashTag hashTag : hashTags) {
            post.addHashTag(hashTag);
        }

        return post;
    }
}

위 코드에서 Post와 HashTag의 연관관계를 설정하는 부분은 아래 부분이다.

@OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
private List<HashTag> hashTags = new ArrayList<>();

각 코드들은 아래의 의미를 지닌다.

  • @OneToMany -> 1:N 관계임을 명시 (Post가 1, HashTag가 N)
  • mappedBy = "post" -> HashTag class의 post와 매핑되는 값임을 나타낸다.
  • cascade = CascadeType.ALL -> HashTags가 영속(persist) 될 때 HashTag Entity도 함께 영속된다.

참고

addHashTag()라는 메서드는 엔티티가 서로 참조하고 있는 경우(양방향 관계) 서로 값을 가져올 수 있게 원자적으로 묶어주기 위함이다.
Post에서 HashTag의 값들을 가져오기 위해, 또는 HashTag에서 Post값을 가져오기 위해서 만든 매서드라고 생각하면 된다.

 

HashTag Entity

@Entity
@Getter @Setter
@Table(name = "tbl_hashtag")
public class HashTag {

    @Id @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "board_id")
    private Post post;

    private String tag;

    public static HashTag createHashTag(WhatsNew whatsNew, String tag) {
        HashTag hashTag = new HashTag();
        hashTag.setWhatsNew(whatsNew);
        hashTag.setTag(tag);

        return hashTag;
    }
}

위 코드에서 HashTag와 Post의 연관관계를 설정하는 부분은 아래 부분이다.

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;

각 코드들은 아래의 의미를 지닌다.

  • @ManyToOne -> N:1 관계임을 명시 (HashTag가 N, Post가 1)
  • fetch = FetchType.LAZY -> HashTag를 조회할 때 즉시 매핑된 Post값을 가져오는 것이 아닌,
    HashTag에서 post값을 꺼내 사용하는 시점에 조회한다. 일종의 더티 체킹기능
  • @JoinColumn(name = "post_id") -> 연관 관계에서 FK를 HashTag가 갖도록 설정.
    name 옵션에 지정되는 값은 DB에서 Column명이 된다.

참고

사실 거의 같은 말이지만 1:N 매핑이나 N:1에서 FK는 Many 쪽이 가지고 있어야 한다.

(김영한 님은 'Many' 쪽이 관계의 주인이다'라고 표현하심)

'Spring' 카테고리의 다른 글

Spring을 이용한 API개발 - 기본  (0) 2021.10.11
Spring JPA 준영속 엔티티 수정하기  (0) 2021.10.11
Spring JPA Entity 설계 시 주의점  (0) 2021.10.11
Spring Bean의 생명주기  (0) 2021.10.10
Spring Bean 등록/설정 방법  (0) 2021.10.04