개발강의정리/Spring

[스프링 데이터 JPA] 3-5. 스프링 데이터 Common: 쿼리 만들기 실습

nineDeveloper 2019. 11. 23.
728x90

스프링 데이터 JPA

3. 스프링 데이터 Common

본격적인 스프링 데이터 JPA 활용법을 학습하기에 앞서, ORM과 JPA에 대한 이론적인 배경을 학습합니다

포스팅 참조 정보

GitHub

공부한 내용은 GitHub에 공부용 Organizations에 정리 하고 있습니다

해당 포스팅에 대한 내용의 GitHub 주소

실습 내용이나 자세한 소스코드는 GitHub에 있습니다
포스팅 내용은 간략하게 추린 핵심 내용만 포스팅되어 있습니다

https://github.com/freespringlecture/spring-data-jpa-study/tree/chap03-05_common_query_make

해당 포스팅 참고 인프런 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-jpa/dashboard

실습 환경

  • Java Version: Java 11
  • SpringBoot Version: 2.1.2.RELEASE

5. 스프링 데이터 Common: 쿼리 만들기 실습

실습 예제

Repository bean을 생성할 때 쿼리 메서드에 해당하는 쿼리도 생성을 하고
애플리케이션의 빈에 등록이 되기 때문에 쿼리를 제대로 못만드는 경우 에러가 남

findByCommentContains 메서드 추가

public interface CommentRepository extends MyRepository<Comment, Long>{
    List<Comment> findByCommentContains(String keyword);
}

쿼리 테스트

SpringS가 대문자라서 해당하는 Comment가 없다고 에러가 남

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

    @Autowired
    CommentRepository commentRepository;

    @Test
    public void crud() {
        Comment comment = new Comment();
        comment.setComment("spring data jpa");
        commentRepository.save(comment);

        List<Comment> comments = commentRepository.findByCommentContains("Spring");
        assertThat(comments.size()).isEqualTo(1);
    }
}

IgnoreCase 추가

upper를 적용하여 값을 모두 대문자로 변경해서 조회하므로 에러가 나지 않음

List<Comment> findByCommentContainsIgnoreCase(String keyword);

likeCount가 특정 숫자보다 높을 때 조건 추가

List<Comment> findByCommentContainsIgnoreCaseAndLikeCountGreaterThan(String keyword, int likeCount);

likeCount 값을 초기화

private Integer likeCount = 0;

likeCount 적용 쿼리 테스트

Comment comment = new Comment();
comment.setLikeCount(1);
comment.setComment("spring data jpa");
commentRepository.save(comment);

List<Comment> comments = commentRepository.findByCommentContainsIgnoreCaseAndLikeCountGreaterThan("Spring", 10);
assertThat(comments.size()).isEqualTo(0);

Comment를 likeCount 높은 순으로 정렬

List<Comment> findByCommentContainsIgnoreCaseOrderByLikeCountDesc(String keyword);
@Test
public void crud() {
    this.createComment(100, "spring data jpa");
    this.createComment(55, "HIBERNATE SPRING");

    List<Comment> comments = commentRepository.findByCommentContainsIgnoreCaseOrderByLikeCountDesc("Spring");
    assertThat(comments.size()).isEqualTo(2); // 2개의 결과가 있고
    assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount", 100); // 첫번째 값의 likeCount = 100
}

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

ASC 도 테스트

List<Comment> findByCommentContainsIgnoreCaseOrderByLikeCountAsc(String keyword);
List<Comment> comments = commentRepository.findByCommentContainsIgnoreCaseOrderByLikeCountAsc("Spring");
assertThat(comments.size()).isEqualTo(2); // 2개의 결과가 있고
assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount", 55); // 첫번째 값의 likeCount = 55

Pageable로 동적으로 정렬

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

DESC로 정렬

PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "LikeCount"));

Page<Comment> comments = commentRepository.findByCommentContainsIgnoreCase("Spring", pageRequest);
assertThat(comments.getNumberOfElements()).isEqualTo(2);
assertThat(comments).first().hasFieldOrPropertyWithValue("likeCount", 100);

Stream으로 받아오기

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

Stream 으로 받아 오는 로직

StreamStream을 받고 난 다음 닫아줘아함

PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "LikeCount"));
try(Stream<Comment> comments = commentRepository.findByCommentContainsIgnoreCase("Spring", pageRequest)) {
    Comment firstComment = comments.findFirst().get(); //첫번째 값 조회
    assertThat(firstComment.getLikeCount()).isEqualTo(100); //첫번째 likeCount 값은 100
}

기본 예제

List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// distinct
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// ignoring case
List<Person> findByLastnameIgnoreCase(String lastname);
// ignoring case
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

정렬

List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);

페이징

Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);

스트리밍

try-with-resource 사용할 것 (Stream을 다 쓴 다음에 close() 해야 함)

Stream<User> readAllByFirstnameNotNull();
728x90

댓글

💲 추천 글