TIL] 스프링부트+JPA 로 게시판에 해시태그 기능을 구현해보자 -1

BRINCE·2022년 10월 28일
0

해시태그

해시태그 라는걸 생각하면 무엇이 가장 먼저 떠오를까?

그렇다. 인스타그램이나 트위터의 해시태그 기능이 떠오를것이다. (마찬가지로 숏폼 컨텐츠 등.. 굉장히 여러곳에서 사용되는 기능이다.)

해시태그를 구현할때 , 단순히 그냥 한 해시태그를 등록하게 설계해 검색으로 해당 해시태그가 등록된 글을 찾을 수 있게 구현을 할 순 있다.

하지만 단건으로 등록을 한다면?

해시태그의 본질은

내가 해당 주제에 대해서 검색을 했을때,해당 주제에 대해 쓰여진 모든 글을 볼 수 있어야 하고, 마찬가지로 한가지 주제가 아니라면 해시태그는 두개 이상이 등록이 가능해야 한다.

단순히 기능 구현만을 위한 목적이라면 단건으로 등록해 게시글 엔티티에서 해시태그를 관리하게 도메인을 설계할 순 있다.

단건으로 설계를 해볼까?

단건으로 설계할때는 굉장히 간단하다.

단순히 게시글 (Article) 엔티티에 varchar(50) 정도 되는 해시태그 컬럼을 배정해주면 된다.


이미지 출처 - 해시태그 구현하기 / juna-dev.log
이런식으로 하나만 등록해 구현하게 할 수 있다.

이 경우에 우리가 흔히 생각하는 해시태그의 기본 기능인 해당 해시태그가 등록된 게시글을 검색할 수 있다.

하지만 이게 맞을까?

해시태그는 말그대로 해당 주제에 대해서 단어나 문장별로 정리를 해주는 중간 역할이라고 볼 수 있다.

(퍼온 예제이다.정국님 생일축하드려요..)

이렇게 어떻게 보면 게시글 <-> 해시태그 가 서로 양방향 관계를 가진다고 볼 수 있다.

JPA 에서는 이런 상황들을 위해 OneToOne 부터 ManyToMany 까지 다양한 양방향 맵핑을 지원해준다.

설계를 바꿔서 연관관계를 재설계 해보자.

기존에 설계 했던 도메인은 게시글 에 하나의 해시태그 가 들어가는 구조였다.

이제 새로 해야할것은 다른 Hashtag 테이블을 만들어 Article 테이블과 연관관계를 설정해주는 것이다.

이렇게 단순 기능 구현을 위한 hashtag 엔티티를 새로 생성해주고,

따로 엔티티는 아니지만 JoinTable 로 각각 게시글 , 해시태그 엔티티에 서로의 id 값을 FK 로 잡을 수 있는 양방향 맵핑 테이블을 설정해준다.

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

    @Setter
    @Column(nullable = false)
    private String hashtag;

    @ToString.Exclude
    @ManyToMany(mappedBy = "hashtags")
    private Set<Article> articles = new LinkedHashSet<>();

이렇게 해시태그 도메인을 생성해주고, 한 해시태그에 여러개의 게시글이 담겨올 수 있으니 HashSet으로 게시글을 담아주도록 ManyToMany 관계를 맺어준다.
(ToString.Exclude 는 무한참조를 방지하기 위한 어노테이션이다.)

    @ToString.Exclude
    @JoinTable(
            name = "article_hashtag",
            joinColumns = @JoinColumn(name = "articleId"),
            inverseJoinColumns = @JoinColumn(name = "hashtagId")
    )
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<hashtag> hashtags = new LinkedHashSet<>();

마찬가지로 게시글 엔티티에도 해시태그들을 모아올 수 있게 ManyToMany 로 해시태그를 담을 HashSet를 선언해주고 맵핑을 해준다.

@JoinTable은 JPA의 연관관계 맵핑을 위한 어노테이션으로 엔티티가 아닌 별도의 테이블을 생성해줘 연관관계를 맺을 수 있게 도와준다.
(해당 어노테이션 속 name 은 테이블 이름, joinColumns 는 각각 연관관계를 맺을 테이블의 요소를 입력해주면 된다 .)

여기서 cascad 로 영속성전이 설정을 해주지 않으면 SQL오류가 발생하니 꼭 설정해주자.

-2 로 이어집니다.

profile
자스코드훔쳐보는변태

0개의 댓글