게시물을 제목으로 검색할 수 있는 기능을 만들어본다.
(페이징 적용)
검색 기능 적용하기
1. Repository
public interface ArticleRepository extends JpaRepository<Article,Long> {
...
Page<Article> findByTitleContaining(String keyword,Pageable pageable);
}
JpaRepository를 상속받는 레파지토리 인터페이스에,
findBy{필드명}Containing({타입} 검색어) 형식으로 메소드를 작성한다.
나는 Article엔티티에 String타입의 title이 있고, 이 title을 이용해서 검색할것이기 때문에
findByTitleContaining(String keyword) 로 작성했다.
그럼, title필드에 keyword가 포함되는 엔티티를 반환받을 수 있다.
SELECT * FROM articles WHERE title LIKE '%Spring%';
만약 findByTitleContaining("Spring")을 호출하면 위와 같은 쿼리가 나간다.
또한, 페이징을 위해 파라미터에 Pageable을 추가하고, 반환타입을 Page<Article>로 작성하였다.
2. Controller
@GetMapping("/forum/search")
public String searchArticle(@RequestParam String keyword,@PageableDefault(sort = "id", size=2,direction = Sort.Direction.DESC)
Pageable pageable, Model model){
Page<ArticleDto> articlePage = articleService.searchByTitle(pageable, keyword);
model.addAttribute("articlePage",articlePage);
model.addAttribute("hasPrev",articlePage.hasPrevious());
model.addAttribute("hasNext",articlePage.hasNext());
model.addAttribute("previous",articlePage.previousOrFirstPageable().getPageNumber());
model.addAttribute("next",articlePage.nextOrLastPageable().getPageNumber());
model.addAttribute("keyword",keyword);
return "articles/search";
}
/forum/search로 접속하면 검색결과를 볼 수 있도록 했다.
검색어를 @RequestParam String keyword로 받았고, 페이징을 위해 파라미터에 Pageable을 추가했다. 또, 뷰로 값을 전달하기 위해 Model을 파라미터에 추가했다.
파라미터로 받은 pageable과 keyword를 서비스 메소드로 넘겨 Page<ArticleDto>를 반환받는다.
3. Service
public Page<ArticleDto> searchByTitle(Pageable pageable, String keyword) {
Page<ArticleDto> articleDtos = articleRepository.findByTitleContaining(keyword,pageable).map(ArticleDto::createArticleDto);
return articleDtos;
}
pageable과 keyword를 파라미터로 받고, 레파지토리에 작성해둔 메소드 findByTitleContaining을 호출하여 Page<Article> 객체를 반환받는다. Page<ArticleDto>로 변환하기 위해 .map메소드를 이용하였다.
4.View
{{>layouts/header}}
<div class="input-group mb-3">
<input type="text" class="form-control" id="keywordInput" placeholder="제목" >
<button class="btn btn-outline-secondary" type="button" id="searchButton">검색</button>
</div>
<h2>"{{keyword}}"에 대한 검색 결과</h2>
{{#articlePage.content}}
<div class="card mt-3">
<div class="card-body">
<h5 class="card-title"><a href="/forum/{{id}}">{{title}}</a></h5>
<h6 class="card-subtitle mb-2 text-muted">{{nickname}}/{{createdAt}}</h6>
</div>
</div>
{{/articlePage.content}}
<a href="/forum/new" class="btn btn-outline-primary mt-3">create article</a>
<!-- 현재 페이지 번호 출력 -->
<p>Current Page: {{articlePage.number}}</p>
<!-- 총 페이지 수 출력 -->
<p>Total Pages: {{articlePage.totalPages}}</p>
<!-- 총 엔티티 수 출력 -->
<p>Total Elements: {{articlePage.totalElements}}</p>
<div class="pagination justify-content-center">
{{#hasPrev}}
<a href="?keyword={{keyword}}&page={{previous}}" role="button" class="btn btn-lg btn-danger bi bi-caret-left-square-fill"><</a>
{{/hasPrev}}
{{^hasPrev}}
<a href="?keyword={{keyword}}&page={{previous}}" role="button" class="btn btn-lg btn-danger bi bi-caret-left-square-fill disabled"><</a>
{{/hasPrev}}
{{#hasNext}}
<a href="?keyword={{keyword}}&page={{next}}" role="button" class="btn btn-lg btn-primary bi bi-caret-right-square-fill">></a>
{{/hasNext}}
{{^hasNext}}
<a href="?keyword={{keyword}}&page={{next}}" role="button" class="btn btn-primary btn-lg bi bi-caret-right-square-fill disabled">></a>
{{/hasNext}}
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// 엔터 키를 누를 때 이벤트 핸들러 등록
$("#keywordInput").on("keypress", function(event) {
// 엔터 키의 keycode는 13입니다.
if (event.keyCode === 13) {
// 검색 버튼 클릭
$("#searchButton").click();
}
});
// 검색 버튼 클릭 이벤트 핸들러 등록
$("#searchButton").on("click", function() {
// input에서 키워드 가져오기
var keyword = $("#keywordInput").val();
// 키워드가 비어있지 않은 경우에만 검색 요청 보내기
if (keyword.trim() !== "") {
// 검색 요청 URL 생성
var searchUrl = "/forum/search?keyword=" + encodeURIComponent(keyword);
// GET 요청 보내기
window.location.href = searchUrl;
}
});
});
</script>
{{>layouts/footer}}
Controller로부터 받은 값들을 적절하게 보여준다.
또, 검색창을 두어 검색버튼을 눌렀을 때, /forum/search?keyword=검색어 경로로 get요청을 하도록했다.
'웹개발 > SpringBoot' 카테고리의 다른 글
파일 업로드 구현하기 (0) | 2023.07.27 |
---|---|
네이버 검색 API를 이용하기 (0) | 2023.07.26 |
페이징 기능 적용하기 (0) | 2023.07.26 |
swagger 작성해보기, Springboot swagger 연동하기 (0) | 2023.07.05 |
MySQL 설치 및 Spring 연동 방법 (0) | 2023.06.09 |
댓글