-
[ Spring Boot + JPA + Thymeleaf ] 검색 기능 구현Spring Boot 2021. 3. 4. 21:46
검색기능
- 게시판 리스트에서 검색어를 입력 후 버튼을 누르면 제목과 내용에 해당 검색어가 포함되는 리스트들을 출력해주는 기능을 구현 할 것이다.
1. Controller
- BoardController.java
@Controller @RequestMapping("/board") public class BoardController { @Autowired private BoardRepository boardRepository; @Autowired private BoardValidator boardValidator; // 리스트 출력 @GetMapping("/list") public String list(Model model, @PageableDefault(size = 2) Pageable pageable, @RequestParam(required = false, defaultValue = "") String searchText){ //Page<Board> boards = boardRepository.findAll(pageable); Page<Board> boards = boardRepository.findByTitleContainingOrContentContaining(searchText,searchText,pageable); int startPage = Math.max(1,boards.getPageable().getPageNumber() - 4); int endPage = Math.min(boards.getTotalPages(),boards.getPageable().getPageNumber() + 4); model.addAttribute("startPage",startPage); model.addAttribute("endPage",endPage); model.addAttribute("boards", boards); return "board/list"; }
우선 검색기능 구현을 위해 검색어 값을 넘겨받아야 하므로 searchText인자를 추가해주었다. 그리고 해당 값이 없을 경우도 있기떄문에 에러방지를 위해 @RequestParam의 required값을 false로 두었다. 그리고 제목과 내용에서 해당 검색어가 포함되는 리스트를 출력하기 위해서 findByTitleContainingOrContentContaining메서드를 사용해 주었다.
이제 findByTitleContainingOrContentContaining을 repository에 선언해주면 된다.
2. Repository
- BoardRepository.java
package com.example.myhome.repository; import com.example.myhome.model.Board; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface BoardRepository extends JpaRepository<Board, Long> { List<Board> findByTitle(String title); List<Board> findByTitleOrContent(String title,String content); Page<Board> findByTitleContainingOrContentContaining(String title, String content, Pageable pageable); }
3. View
- list.html
<!doctype html> <html xmlns:th="http://www.thymelef.org"> <head th:replace="fragments/common :: head('게시판')"> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('list')"> </nav> <div class="container"> <h2>게시판</h2> <div>총 건수 : <span th:text="${boards.totalElements}"></span></div> <form class="row g-3 align-items-center d-flex justify-content-end" method="GET" th:action="@{/board/list}"> <div class="col-auto"> <label for="searchText" class="col-form-label">검색</label> </div> <div class="col-auto"> <input type="text" id="searchText" class="form-control" name="searchText" th:value="${param.searchText}"> </div> <div class="col-auto"> <button type="submit" class="btn btn-light">검색</button> </div> </form> <table class="table"> <thead> <tr> <th scope="col">번호</th> <th scope="col">제목</th> </tr> </thead> <tbody> <tr th:each="board : ${boards}"> <th th:text="${board.id}">1</th> <td><a th:text="${board.title}" th:href="@{/board/form(id=${board.id})}" >Mark</a></td> </tr> </tbody> </table> <nav aria-label="Page navigation example"> <ul class="pagination"> <li class="page-item" th:classappend="${1 == boards.pageable.pageNumber+1} ? 'disabled' "> <a class="page-link" href="#" th:href="@{/board/list(page=${boards.pageable.pageNumber-1},searchText=${param.searchText})}">Previous</a> </li> <li class="page-item" th:classappend="${i == boards.pageable.pageNumber+1} ? 'disabled' " th:each="i : ${#numbers.sequence(startPage,endPage)}"> <a class="page-link" href="#" th:text="${i}" th:href="@{/board/list(page=${i-1},searchText=${param.searchText})}">1</a> </li> <li class="page-item" th:classappend="${boards.totalPages == boards.pageable.pageNumber+1} ? 'disabled' "> <a class="page-link" href="#" th:href="@{/board/list(page=${boards.pageable.pageNumber+1},searchText=${param.searchText})}">Next</a> </li> </ul> </nav> <div class="text-right"> <a type="button" class="btn btn-primary" th:href="@{/board/form}">글쓰기</a> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> </body> </html>
검색 버튼을 누를경우 위의 코드들이 실행되면서 결과에 맞는 값을 뿌려준다. 그런데 페이지가 새로고침되면서 입력했던 검색어 글자가 초기화되는것을 볼 수 있다. 그것을 방지하기 위해서 파라미터로 표현되있는 검색어값을 input의 value값에 넣어주는 코드를 추가해줄것이다.
th:value="${param.searchText}"
해당 코드를 넣어주면 된다.
아, 그리고 페이징 이동시에도 해당값이 초기화되기때문에 페이징 url넘길때 searchText값도 같이 넘겨주어야 한다.
실행화면
'Spring Boot' 카테고리의 다른 글
[ Spring Boot + JPA + Thymeleaf ] 댓글 기능 구현 (0) 2021.03.18 [ Spring Boot + JPA + Thymeleaf ] 페이징 기능 구현 (0) 2021.03.04 [ Spring Boot + JPA + Thymeleaf ] validation 추가 (0) 2021.03.02 [ Spring Boot + JPA + Thymeleaf ] 로그인/회원가입 (0) 2021.02.23 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 3 (0) 2021.02.10