게시판 검색 기능 구현하기

친친·2022년 10월 26일
0


이번에는 게시글 제목을 검색할 수 있는 검색 기능을 구현한다. JPA에서 제공하는 findBy(컬럼명)[Containing]이란 메서드명 조합을 이용하면 DB 테이블에 있는 id, title, content 등의 컬럼 데이터들을 조회할 수 있다. 전체 흐름은 다음과 같다.

  • boardRepository.java에서 title명으로 데이터를 조회해서 반환하는 메서드를 정의한다.
  • boardRepository에서 새로 정의한 메서드를 boardService.java에도 추가한다.
  • boardController.java에서 검색키워드 유무에 따라 반환하는 페이지가 달라지도록 처리 프로세스를 변경한다.
  • boardlist.html에서 키워드검색 결과를 반영하도록 페이지 블럭 코드를 수정하고, 그 밑에 검색창과 검색 버튼도 추가해준다.

//boardRepository.java

@Repository
public interface BoardRepository extends JpaRepository<Board, Integer> {

    Page<Board> findByTitleContaining(String searchKeyword, Pageable pageable);
}

Jpa에서는 메서드명을 통해 데이터를 검색하는 쿼리기능을 수행하게 된다. 예를 들어, findBy(컬럼명)은 검색키워드와 정확히 일치하는 데이터를 찾고, findBy(컬럼명)Containing은 검색키워드를 포함하는 데이터를 모두 찾아서 리턴해준다. 따라서 findByTitleContaining() 메서드는 Title이란 컬럼에서 검색키워드를 포함한 데이터를 찾아 리턴하게 된다.

boardRepository에 검색키워드와 Pageable을 매개변수로 받아서 Page타입으로 반환하는 findByTitleContaining()을 정의한다.

JPA findBy메서드 명명규칙


//boardService.java
...
    public Page<Board> boardSearchList(String searchKeyword, Pageable pageable){

        return boardRepository.findByTitleContaining(searchKeyword, pageable);
    }
...

boardRepository에서 새로 정의한 메서드를 사용하는 boardSearchList()를 boardService에 추가한다.


boardController.java
...
    @GetMapping("/board/list")
    public String boardList(Model model,
                            @PageableDefault(page = 0, 
                            size = 10, sort="id", 
                            direction = Sort.Direction.DESC) Pageable pageable,
                            String searchKeyword){

        Page<Board> list = null;
		
        //searchKeyword 유무에 따른 분기
        if(searchKeyword != null){

            list = boardService.boardSearchList(searchKeyword, pageable);
        }else {

            list = boardService.boardList(pageable);
        }

		int nowPage = list.getPageable().getPageNumber() + 1; 
        int startPage =Math.max(nowPage -4, 1);
        int endPage = Math.min(nowPage + 5, list.getTotalPages());

        model.addAttribute("list", list);
        model.addAttribute("nowPage", nowPage);
        model.addAttribute("startPage", startPage);
        model.addAttribute("endPage", endPage);

        return "boardlist";
    }
    ...

if~else 문을 이용하여 검색키워드로 검색할 때는 boardSearchList() 메서드를, 검색키워드 없이 페이지만 조회할 경우에는 boardList() 메서드를 사용하도록 변경한다.


//boardlist.html
...
 	 <!--페이지 블럭-->
	 <th:block th:each="page : ${#numbers.sequence(startPage, endPage)}">
      	<a th:if="${page != nowPage}" 
         	th:href="@{/board/list(page = ${page -1}, searchKeyword = ${param.searchKeyword})}" 
         	th:text="${page}">
        </a>
      	<strong th:if="${page == nowPage}" th:text="${page}" style="color: orangered"></strong>
 	 </th:block>

	 <!--검색창-->
	 <form th:action="@{/board/list}" method="get">
    	<input type="text" name="searchKeyword"/>
    	<button type="submit">검색</button>
	 </form>
...

검색키워드가 페이지 블럭에도 반영될 수 있도록 a태그의 th:href 속성에
"searchKeyword = ${param.searchKeyword}"를 추가한다.
위 코드처럼 href 속성에 "(page = ${page -1}, searchKeyword = ${param.searchKeyword})"로 요청하면,
url 뒤에 "? page=n&searchKeyowrd=string" 와 같이 쿼리 스트링으로 전달된다.

타임리프 문법
param.key => url에서 key와 매칭된 value를 찾아 값을 반환한다




[출처] 한코딩

profile
웹개발 블로그

0개의 댓글