제일 복잡할 것 같아서 미루고 미루었던 팔로워, 팔로잉 기능 구현을 시작했다.
구체적인 기능은 인스타그램을 많이 참고하였다.
기능설명
<팔로우 걸기>
- A 사용자가 B 사용자 프로필에서 '팔로우' 버튼을 누르면 버튼은 '팔로잉'으로 변한다.
- A 사용자의 '팔로잉' 목록에 B 사용자가 추가된다.
- B 사용자의 '팔로워' 목록에 A 사용자가 추가된다.
<팔로우 취소>
- A 사용자가 B 사용자를 그만 '팔로우'하고 싶으면,
B 사용자 프로필 또는 '팔로잉' 목록에서 '팔로잉' 버튼을 누른다.
버튼을 누르면 '팔로우'로 변한다. '팔로잉' 목록을 다시 들어가 보면 B 사용자가 목록에 존재하지 않는다.
실제 인스타그램에서는 비공개 계정인 경우 팔로우도 승인을 해야 걸 수 있지만,
일단은 아무나 팔로우를 걸 수 있도록 만들 것이다.
잠깐 생각을 해보아도 DB 설계가 관건임을 알 수 있었다.
구글링을 해보니 크게 두 가지 방법으로 팔로우 기능을 구현하고 있었다.
첫 번째 방법이 가장 많았는데, 바로 User 엔티티 안에 FollowerList와 FollowingList를 만드는 것이었다.
(챗지피티한테도 물어봤었는데, 이 방법을 추천해 주었다.)
두 번째는 Follow 엔티티를 따로 만드는 것이다.
엔티티 안에는 팔로우를 요청한 유저와 팔로우를 요청받은 유저가 들어가게 된다.
.
.
.
이중 나는 두번째 방식으로 구현할 것이다.
첫 번째 방법: User Entity 안에 FollowerList와 FollowingList
가장 먼저 생각할 수 있는 이 방법의 단점은 A 유저의 요청임에도 불구하고,
B 유저의 엔티티에 직접 접근해서 수정해야 한다는 것이다.
이제부터 설명을 위해 팔로우를 요청하는 사용자를 from_user, 팔로우를 요청받은 사용자를 to_user라고 하자.
한 사람은 여러 명에게 팔로우 요청을 할 수 있을뿐만 아니라 여러명에게 팔로우 요청을 받을 수 있다.
즉, from_user와 to_user는 다대다 관계라는 것이다.
이때, 우리는 일대다, 일대일 관계에서 @OneToMany, @OneToOne 어노테이션을 사용하는 것처럼
다대다 관계에서도 @ManyToMany 어노테이션을 사용하는 것을 고려할 수 있다.
하지만 @ManyToMany 어노테이션은 사용을 권장하지 않는다.
왜냐하면 @ManyToMany 어노테이션을 사용할 경우 내부적으로 중간 테이블이 생성되어 개발자가 알지 못하는 쿼리가 발생하기 때문이다.
또한 생성된 테이블에 필요한 컬럼을 추가할 수 없어 유지·보수가 불편하다.
이런 경우 연결 Entity를 직접 생성하는 것이 권장된다.
따라서 나도 이 방법을 이용하여 팔로우 기능을 구현할 생각이다.
두 번째 방법: Follow Entity(연결 Entity) 만들기
User Entity
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long user_id;
@Column(name = "user_name")
private String userName;
private String password;
private String email;
private String role;
//프로필 사진
private String profile;
//팔로우
@OneToMany(mappedBy = "from_user", fetch = FetchType.LAZY)
private List<Follow> followings;
@OneToMany(mappedBy = "to_user", fetch = FetchType.LAZY)
private List<Follow> followers;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Diary> diaries;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Book> books;
}
중간 테이블인 Follow Entity를 간단하게 구현해 보았다.
package com.site.bemystory.domain;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.springframework.data.annotation.CreatedDate;
import java.sql.Timestamp;
@Entity
@Data
public class Follow {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "follow_id")
private long id;
@ManyToOne
@JoinColumn(name = "from_user")
private User from_user;
@ManyToOne
@JoinColumn(name = "to_user")
private User to_user;
@CreationTimestamp
@Column(name = "create_date")
private Timestamp createDate;
}
Service, Controller는 다음 포스트에서 소개하겠다.
참고
[JPA-다대다-N-N-관계-풀어내기-중간-테이블-생성]
[인스타그램 팔로우 관계는 어떻게 관리될까?]
https://velog.io/@evelyn82ny/instagram-follow#%EC%83%9D%EA%B0%81-1
'캡스톤프로젝트' 카테고리의 다른 글
[HTTP Method] PUT vs PATCH 결정하기 (0) | 2023.09.22 |
---|---|
[Nginx, Amazon Linux] Certbot을 이용한 https 인증받기 (0) | 2023.09.13 |
졸업프로젝트, 태초마을로 돌아가다 (0) | 2023.09.02 |
[SpringBoot] 팔로워, 팔로잉 기능 구현하기 2 (0) | 2023.08.30 |
Jenkins, EC2를 이용한 Springboot의 CI/CD 파이프라인 구축 (1) | 2023.05.26 |