[게시판] 게시글 좋아요 / 좋아요 취소
2023. 1. 25. 16:19ㆍ프로젝트/라이프 챌린지
728x90
SMALL
추가적인 기능 요소인 게시글 좋아요 기능을 만들어줄 것이다.
PostController
// 게시글 좋아요
@PostMapping("/post/like/{post_id}")
public ResponseEntity<ResponseBody> postLike(HttpServletRequest request, @PathVariable Long post_id){
log.info("게시글 좋아요 - 좋아요를 누른 유저 : {}, 좋아요한 게시글 : {}", jwtTokenProvider.getMemberFromAuthentication().getNickname(), post_id);
return postService.postLike(request, post_id);
}
좋아요 api를 만들어준다.
- 좋아요한 정보가 저장될 것이므로 PostMapping 으로 method 타입을 지정해준다.
- Service 단에 넘길 인자값은 HttpServletRequest, 좋아요할 게시글의 post_id.
MemberLikePost
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class MemberLikePost {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long memberlikepost_id;
@JsonIgnore
@JoinColumn(name = "member_pk_id")
@ManyToOne(fetch = FetchType.LAZY)
private Member member;
@JsonIgnore
@JoinColumn(name = "post_pk_id")
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
}
좋아요와 좋아요 취소를 구분하기위해 좋아요 이력을 저장한 엔티티를 만들어준다.
- Member 객체를 ManyToOne 으로 지정하여 속성으로 만들어준다. 유저 한 명당 여러 게시글을 좋아요할 수 있기 때문에 ManyToOne으로 지정해주었다.
- @JoinColumn을 통해 member_pk_id(member 고유 id)로 지정하여 넣겠다고 명시해준다.
- FetchType.LAZY 로 지정하여 Post까지 한번에 조회될 수 있는 문제를 예방한다. (N+1 문제)
- Post 객체를 ManyToOne 으로 지정하여 속성으로 만들어준다. 한 게시글 당 여러명이 좋아요를 할 수 있기 때문이다.
- @JoinColumn을 통해 posT_pk_id(post 고유 id)로 지정하여 넣겠다고 명시해준다.
- FetchType.LAZY 로 지정하여 Post까지 한번에 조회될 수 있는 문제를 예방한다. (N+1 문제)
Member
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Entity
public class Member extends Timestamped {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long member_pk_id;
@Column(nullable = false)
private String member_id;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String nickname;
@Column(nullable = false)
private String address;
@ElementCollection(fetch = FetchType.EAGER)
@Builder.Default
private List<String> roles = new ArrayList<>();
@JsonIgnore
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts;
@JsonIgnore
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<MemberLikePost> likePosts;
}
MemberLikePost 엔티티와 연관관계를 맺었으니 MemberLikePost에 대한 필드값을 추가 생성해준다.
- 일대다(OneToMany) 연관관계를 맺었으므로 MemberLikePost는 List로 만들어야한다.
- @JsonIgnore를 지정함으로서, Member 객체를 조회할 때 MemberLikePost는 조회될 수 없게끔 무시할 수 있도록 만든다.
- 일대다 관계(@OneToMany)를 지정한다.
- mappedBy를 통해 member 객체에 매핑한다고 명시.
- FetchType.LAZY를 통해 한번에 조회되는 이슈를 방지.
- cascade를 통해 member 가 삭제될 경우 해당되는 MemberLikePost 데이터들도 함께 삭제됨을 명시.
- orphanRemoval을 통해 고아 객체가 발생될경우 삭제처리됨을 명시.
Post
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.List;
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Post extends Timestamped{
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long post_id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column(nullable = false)
private Integer viewcnt;
@Column(nullable = false)
private Integer likecnt;
@JsonIgnore
@JoinColumn(name = "member_pk_id")
@ManyToOne(fetch = FetchType.LAZY)
private Member member;
@JsonIgnore
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<MemberLikePost> likePosts;
}
Post 엔티티에도 MemberLikePost 엔티티와 연관관계를 맺었으니 MemberLikePost에 대한 필드값을 추가 생성해준다.
- 일대다(OneToMany) 연관관계를 맺었으므로 MemberLikePost는 List로 만들어야한다.
- @JsonIgnore를 지정함으로서, Post 객체를 조회할 때 MemberLikePost는 조회될 수 없게끔 무시할 수 있도록 만든다.
- 일대다 관계(@OneToMany)를 지정한다.
- mappedBy를 통해 post 객체에 매핑한다고 명시.
- FetchType.LAZY를 통해 한번에 조회되는 이슈를 방지.
- cascade를 통해 post 가 삭제될 경우 해당되는 MemberLikePost 데이터들도 함께 삭제됨을 명시.
- orphanRemoval을 통해 고아 객체가 발생될경우 삭제처리됨을 명시.
PostService
// 게시글 좋아요
@Transactional
public ResponseEntity<ResponseBody> postLike(HttpServletRequest request, Long post_id){
// 유저 검증
Member auth_member = checkAuthentication(request);
// 좋아요할 게시글 조회
Post like_post = queryFactory
.selectFrom(post)
.where(post.post_id.eq(post_id))
.fetchOne();
// 좋아요가 되었는지 좋아요가 취소되었는지 알기위한 알림 문구
String notice = "";
// 좋아요할 게시글에 이미 좋아요 처리가 되어있는지 확인
if(queryFactory
.selectFrom(memberLikePost)
.where(memberLikePost.member.eq(auth_member).and(memberLikePost.post.eq(like_post)))
.fetchOne() != null){
// 좋아요가 이미 되어있을 경우 MemberLikePost 에서 좋아요 삭제처리
queryFactory
.delete(memberLikePost)
.where(memberLikePost.member.eq(auth_member).and(memberLikePost.post.eq(like_post)))
.execute();
// 좋아요 취소 시 notice에 문구 반영
notice = "좋아요 취소";
}else{
// 유저가 게시글에 좋아요한 이력 저장
MemberLikePost likepost = MemberLikePost.builder()
.post(like_post)
.member(auth_member)
.build();
memberLIkePostRepository.save(likepost);
// 좋아요 시 notica에 문구 반영
notice = "좋아요";
}
// 해당 게시글좋아요 수
Long likeCnt = queryFactory
.select(memberLikePost.count())
.from(memberLikePost)
.where(memberLikePost.post.eq(like_post))
.fetchOne();
// 게시글 likecnt 정보 업데이트
queryFactory
.update(post)
.set(post.likecnt, Integer.parseInt(likeCnt.toString()))
.where(post.post_id.eq(like_post.getPost_id()))
.execute();
return new ResponseEntity<>(new ResponseBody<>(StatusCode.OK.getStatusCode(), StatusCode.OK.getStatus(), notice), HttpStatus.OK);
}
좋아요 처리를 할 Service 로직을 만들어준다.
- checkAuthentication 으로 유효한 유저 검증 처리.
- 좋아요할 게시글 post 객체 불러오기.
- 좋아요가 되었는지 좋아요 취소 처리가 되었는지 확인하기 위한 notice 변수 생성.
- MemberLikPost 에 좋아요한 유저와 좋아요한 게시글 정보 이력이 저장되어있다면 delete 문으로 해당 이력 삭제 + notice에 "좋아요 취소" 문구 저장.
- MemberLikPost 에 좋아요한 유저와 좋아요한 게시글 정보 이력이 저장되어있지않다면 MemberLikePost 에 이력 저장 + notice에 "좋아요" 문구 저장.
- MemberLikePost 에서 해당 게시글에 대한 좋아요 수가 몇개인지 조회.
- 해당 post 객체에 likecnt 수정 업데이트. (좋아요면 +1, 좋아요 취소면 -1)
- 좋아요 / 좋아요 취소 처리 확인은 반환되는 notice 변수로 확인
포스트맨으로 확인.
좋아요 api 를 한번 호출했을 때 정상적으로 좋아요 처리가 된 것을 확인할 수 있고, 두 번 호출하면 좋아요 취소 처리가 된 것을 확인할 수 있다.
728x90
반응형
LIST
'프로젝트 > 라이프 챌린지' 카테고리의 다른 글
[댓글] 댓글 수정 (0) | 2023.01.28 |
---|---|
[댓글] 댓글 작성 (0) | 2023.01.28 |
[게시판] 게시글 전체 목록 조회 (0) | 2023.01.25 |
[게시판] 게시글 조회 (0) | 2023.01.25 |
[게시판] 게시글 삭제 (0) | 2023.01.25 |