본문 바로가기
백엔드/Spring

[Spring JPA] 검색 쿼리 개발

by RoJae 2021. 1. 2.

🚀  들어가며...

  • 검색의 경우 총 네가지를 구상했습니다.
    • 단순 키워드 검색 (좋아요 내림차순)
    • 단순 키워드 검색 (좋아요 오름차순)
    • 페이지 반환, 키워드 검색 (좋아요 내림차순)
    • 페이지 반환, 키워드 검색 (좋아요 오름차순)
  • 좋아요 컬럼의 변수 이름은 likeCount로 하였습니다
    • like는 데이터베이스 예약어이기 때문에 안됩니다.
  • 테스트 케이스는 assertThat()을 사용하여 진행하였습니다.

 

💌 소스코드

  • 도메인 클래스 (Comment)
package org.rojae.examples;

import org.springframework.lang.NonNull;

import javax.persistence.*;

@Entity
public class Comment {

    @Id @GeneratedValue
    private Long id;

    @Column
    private String comment;

    @ManyToOne(fetch = FetchType.EAGER)
    private Post post;

    @NonNull
    private Integer likeCount = 0;

    @NonNull
    public Integer getLikeCount() {
        return likeCount;
    }

    public void setLikeCount(@NonNull Integer likeCount) {
        this.likeCount = likeCount;
    }

    public Long getId() {
        return id;
    }

    public String getComment() {
        return comment;
    }

    public Post getPost() {
        return post;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public void setPost(Post post) {
        this.post = post;
    }
}

 

  • 레파지토리 (JPQL)
package org.rojae.examples;


import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface CommentRepository extends MyRepository<Comment, Long>{

    // keyword의 문자를 대문자로 바꾸어 준다
    List<Comment> findByCommentContainsIgnoreCaseOrderByLikeCountDesc(String keyword);

    List<Comment> findByCommentContainsIgnoreCaseOrderByLikeCountAsc(String keyword);

    // Page
    Page<Comment> findByCommentContainsIgnoreCase(String keyword, Pageable pageable);


}

 

  • 테스트 코드 작성
package org.rojae.examples;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@DataJpaTest
public class CommentRepositoryTest {

    @Autowired
    CommentRepository commentRepository;

    @Test
    public void run(){
        // GIVEN
        this.createComment(100, "SPRING 100 LIKE COUNT");
        this.createComment(50, "SPRING 50 LIKE COUNT");
        this.createComment(10, "SPRING 10 LIKE COUNT");

        // WHEN (단순 키워드 내림차순 검색)
        List<Comment> comments = commentRepository.findByCommentContainsIgnoreCaseOrderByLikeCountDesc("spring");

        // TEST (리스트의 반환 첫번째의 좋아요는 100)
        assertThat(comments.size()).isEqualTo(3);
        assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount" , 100);

        // When (단순 키워드 오름차순 검색)
        comments = commentRepository.findByCommentContainsIgnoreCaseOrderByLikeCountAsc("spring");


        // Test (리스트의 반환 첫번째의 좋아요는 10)
        assertThat(comments.size()).isEqualTo(3);
        assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount" , 10);

        // When (페이지 반환 키워드 검색)
        PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "LikeCount"));
        Page<Comment> pageComment = commentRepository.findByCommentContainsIgnoreCase("spring", pageRequest);

        // Test (내림차순의 경우 첫번째 좋아요는 100이다)
        assertThat(pageComment.getNumberOfElements()).isEqualTo(3);
        assertThat(pageComment).first().hasFieldOrPropertyWithValue("likeCount", 100);

        // When (페이지 반환 키워드 검색)
        pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "LikeCount"));
        pageComment = commentRepository.findByCommentContainsIgnoreCase("spring", pageRequest);

        // Test (오름차순의 경우 첫번째 좋아요는 10이다)
        assertThat(pageComment.getNumberOfElements()).isEqualTo(3);
        assertThat(pageComment).first().hasFieldOrPropertyWithValue("likeCount", 10);

    }

    private void createComment(int likeCount, String txt){
        Comment comment = new Comment();
        comment.setComment(txt);
        comment.setLikeCount(likeCount);
        commentRepository.save(comment);
    }

}

 

 

🙋🏻‍♂️ 후기

CommentRepository ~> findByCommentContainsIgnoreCase(String keyword, Pageable pageable) 의 경우

Pageable을 통해서 오름차순 혹은 내림차순의

JPQL을 생성할 수 있다는 점이 특별하게 와닿았다.

 

인자로 주어진 PageRequest의 Sort에 의해서 쿼리가 생성되는 점이

신선했다~

 

댓글