아카이브

[스프링 데이터 JPA] 스프링 데이터 Common 4. 쿼리 만드는 방법 및 실습 본문

Spring/스프링 데이터 JPA

[스프링 데이터 JPA] 스프링 데이터 Common 4. 쿼리 만드는 방법 및 실습

주멘이 2021. 1. 16. 20:57

스프링 데이터 저장소의 메서드 이름으로 쿼리 만드는 방법

이름을 분석해서 쿼리 만들기 (CREATE)

public interface CommentRepository extends MyRepository<Comment, Long>{
    //Comment title에 Keyword가 들어있는 모든 Comment를 찾아주는 메서드
    List<Comment> findByCommentContains(String Keyword);
}

2. 미리 정의해 둔 쿼리 찾아 사용하기 (USE_DECLARED_QUERY)

    /**
     * 기본값은 JPQL
     * nativeQuery 설정하고 싶으면 nativeQuery = true 추가
     */
    //@Query(value = "SELECT c FROM Comment AS c")
    List<Comment> findByCommentContains(String keyword);

3. 미리 정의한 쿼리 찾아보고 없으면 만들기 (CREATE_IF_NOT_FOUND)

@SpringBootApplication
@EnableJpaRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

 

  • 리턴 타입 {접두어}{도입부} By {프로퍼티 표현식}(조건식)[(And|Or){프로퍼티 표현식}(조건식)]{정렬 조건} (매개변수)

 

Pageable 파라미터 쿼리 테스트

  • 페이징으로 받기 위해서, Pageable 파라미터를 넘겨주면 페이징 정보를 포함하는 Page 타입으로 받을 수 있다.
  • PageRequest는 Pageable을 구현하고 있다.
  • 쿼리 메서드보단 Pageable을 통한 Sorting을 권장한다.
        // Pageable with PageRequest.of() method
        PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "LikeCount"));
        Page<Comment> page = commentRepository.findByCommentContainsIgnoreCase("Spring", pageRequest);
        assertThat(page.getNumberOfElements()).isEqualTo(commentsSize);
        assertThat(page).first().hasFieldOrPropertyWithValue("likeCount", 100);

 

쿼리 찾는 방법

  • 메서드 이름으로 쿼리를 표현하기 힘든 경우에 사용.
  • 저장소 기술에 따라 다름.
  • JPA :  @Query @NamedQuery
  • 적용 우선순위 : @Query -> @NamedQuery

참고사항

  • primitive int로 정의 한경우 not null 적용
  • Integer로 정의할 경우 null 허용(Wrapper class)
  • Like의 경우 예약어라 오류

 

쿼리 만들기 실습

실습 전체  테스트 코드 

@DataJpaTest
class CommentRepositoryTest {

    @Autowired
    CommentRepository commentRepository;

    @Test
    public void queryMakingTest() {
        this.createComment(100, "spring data jpa");
        this.createComment(55, "HIBERNATE SPRING");

        // IgnoreCase 대소문자 처리
        List<Comment> comments = commentRepository.findByCommentContainsIgnoreCase("Spring");   // upper(?)
        int commentsSize = comments.size();
        assertThat(comments.size()).isEqualTo(commentsSize);

        // GreaterThan
        comments = commentRepository.findByCommentContainsIgnoreCaseAndLikeCountGreaterThan("Spring", 10);   // upper(?)
        assertThat(comments.size()).isEqualTo(commentsSize);

        // DESC
        comments = commentRepository.findByCommentContainsIgnoreCaseOrderByLikeCountDesc("Spring");   // upper(?)
        assertThat(comments.size()).isEqualTo(commentsSize);
        assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount", 100);

        // Pageable with PageRequest.of() method
        PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "LikeCount"));
        Page<Comment> page = commentRepository.findByCommentContainsIgnoreCase("Spring", pageRequest);
        assertThat(page.getNumberOfElements()).isEqualTo(commentsSize);
        assertThat(page).first().hasFieldOrPropertyWithValue("likeCount", 100);

        // Stream
        try (Stream<Comment> commentStream = commentRepository.findByCommentContainsIgnoreCaseAndLikeCountLessThan("Spring", 80)) {
            Comment comment = commentStream.findFirst().get();
            assertThat(comment.getLikeCount()).isEqualTo(55);
        }


    }

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


}