프로젝트를 진행하면서 게시글 검색 기능이 필요 했다.
검색 기능을 구현 하는 방법을 알아보자!
Containing
List<Entity> findByTitleContaining(String keyword);
JpaRepository에서는 메소드명의 By 뒷 부분은 SQL의 where 조건 절에 대응된다.
따라서, Containing을 붙여주면 Like 검색이 된다. 즉, %{keyword}% 가 되는것.
=> https://www.baeldung.com/spring-jpa-like-queries 를 참고했다.
내가 직접 구현한 코드
@GetMapping("/search")
public ResponseEntity searchTitle(@RequestParam(value ="title",required = false) String title,
@RequestParam @Positive int page,
@RequestParam @Positive int size){
Page<Question> pageQuestions = questionService.searchByTitle(title, page, size);
List<Question> questions = pageQuestions.getContent();
return new ResponseEntity<>(new MultiResponseDto<>(mapper.questionToQuestionResponseDtos(questions),pageQuestions),HttpStatus.OK);
}
searchTitle 메서드는 "title", "page", "size" 세 가지 파라미터를 받는다.
"title" 파라미터는 선택 사항이며, 이를 통해 사용자가 검색하려는 질문의 제목을 받을 수 있다.
"page"와 "size" 파라미터는 각각 사용자가 원하는 페이지 번호와 한 페이지에 보여줄 항목의 수를 나타낸다.
메서드 내부에서는 questionService의 searchByTitle 메서드를 호출하여 해당 제목을 포함하는 질문들을 찾고, 이를 페이지네이션 형식으로 가져온다.
이후 가져온 데이터를 ResponseEntity 객체에 담아서 클라이언트에게 반환한다.
public Page<Question> searchByTitle(String title,int page, int size){
if(title == null) title = "";
PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by("questionId").descending());
Page<Question> byTitleContaining = questionRepository.findByTitleContaining(title, pageRequest);
return byTitleContaining;
}
먼저, title이 null인 경우 빈 문자열로 초기화하여 에러를 방지한다.
그 다음, 입력 받은 페이지 번호(page)와 페이지 당 크기(size)를 기반으로 PageRequest 객체를 생성한다. 이때 "questionId"를 기준으로 내림차순으로 정렬하는 옵션을 추가하였다.
이렇게 생성한 PageRequest 객체를 이용하여, title을 포함하는 질문들을 Repository에서 검색한다.
마지막으로, 검색 결과를 반환한다.
Page<Question> findByTitleContaining(String title, Pageable pageable);
Question 객체의 title 필드가 입력된 문자열을 포함하는 모든 엔티티를 찾는다.
Pageable 인터페이스를 매개변수로 받아, 반환 결과의 페이지네이션을 지원한다.
실행 결과
title에 '좋아' 가 들어간 글들이 조회가 된걸 확인할 수 있다!