JAVA(SPRINGBOOT)

[SPRINGBOOT] 좋아요 수 표현

본듀 2023. 3. 9. 18:16

CRUD 게시판을 구현하며
좋아요 기능을 추가하며 당연하지만, 놓치고 지나간 것을 정리하고자 글을 작성한다.

먼저, 아래는 좋아요 수를 나타내기 위해 처음 작성한 코드이다.

@Entity
@NoArgsConstructor
@Getter
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

	@Column
    private long heartNum;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "post", orphanRemoval = true)
    private List<Heart> heartList = new ArrayList<>();
	

    @Builder
    public Post(String title, String content, User user) {
        this.title = title;
        this.content = content;
        this.user = user;
        this.heartNum = 0L;
    }
    
    public void like() {
    	this.heartNum++;
    }

    public void unlike() {
        this.heartNum--;
    }

    public PostDto toPostDto() {
        return PostDto.builder()
                .id(this.id)
                .title(this.title)
                .content(this.content)
                .user(this.user.toUserDto())
                .heartNum(this.heartNum)
                .build();
    }

}


//PostService내의 메서드
@Transactional
public ResponseEntity<?> likePost(long id, UserDetailsImpl userDetails) {
    
    //생략
    
    //Heart가 없으면 좋아요, 있으면 좋아요 취소
    if (heart.isEmpty()) {
        heartRepository.save(Heart.builder()
                                    .user(user)
                                    .post(post)
                                    .build());
		post.like();
        return ResponseEntity.ok("좋아요 성공");
    }
    heartRepository.delete(heart.get());
	post.unlike();
    return ResponseEntity.ok("좋아요 취소");
}

Post 클래스에 좋아요 수를 나타내는 heartNum을 컬럼으로 두었다.

좋아요 요청이 오면 요청을 한 User / Post와 연관관계를 가지고 있는 Heart를 찾아
Heart 존재 여부에 따라 객체를 삭제하고 Post.heartNum을 setter로 변경했다.

그러다 문득 Post와 Heart는 양뱡향으로 매핑되어있고,
Post는 List<Heart>에 좋아요가 저장되어있는데
'굳이 따로 heartNum이라는 컬럼을 만들어주어야하나?'라는 생각을 했다.

단순히 List의 size를 컬럼으로 두는 것은 중복된 값을 갖는 것과 비슷하다고 판단하여,
Post가 heartNum 컬럼을 가지지 않고, 
Post를 반환할 때 dto에 heartNum 컬럼을 두어 List의 size를 반환할 수 있도록 아래와 같이 수정했다.

@Entity
@NoArgsConstructor
@Getter
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    
    //heartNum 컬럼 삭제

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "post", orphanRemoval = true)
    private List<Heart> heartList = new ArrayList<>();
	

    @Builder
    public Post(String title, String content, User user) {
        this.title = title;
        this.content = content;
        this.user = user;
    }

	//setter 삭제

    public PostDto toPostDto() {
        return PostDto.builder()
                .id(this.id)
                .title(this.title)
                .content(this.content)
                .user(this.user.toUserDto())
                .heartNum(this.heartList.size()) //반환시 heartList의 사이즈로 좋아요수 반환
                .build();
    }

}

내가 판단한 근거가 타당한지 확신할 수는 없으나 
좋아요 여부 등 heatList에서 파생될 수 있는 컬럼들이 더욱 많아질 수 있기 때문에
위와 같은 수정은 앞으로 Entity를 더욱 명확하게 만들 수 있을 것이라 생각한다.

'JAVA(SPRINGBOOT)' 카테고리의 다른 글

[SPRING SECURITY] 시큐리티 파헤치기 (1)  (0) 2023.03.16
[JPA] PAGEABLE  (0) 2023.03.13
[JAVA] VECTOR  (0) 2023.01.26
[JAVA] GENERIC PROGRAMMING  (2) 2022.12.22
[JAVA] 비교연산자 (==, equals)  (0) 2022.12.16