Day90 - [Spring]검색페이징 ( 게시판 검색 구현 )

2021. 6. 24. 00:08Spring

이전 글인, Day90 - [Spring]페이징, 페이지네이션 과 이어집니다.

 

이번에는 Spring 환경에서 게시판의 검색을 구현하는 방법을 알아 봅시다.

 

검색기능을 만들게 되면, 페이징도 달라지기 때문에, 같이 알아 두셔야 합니다.

 

검색페이징

먼저, 위와 같은 형태의 검색창이 필요하겠죠?

<form> 태그를 이용해서 만들어 주세요.

먼저, "제목, 내용, 작성자, 제목+내용" 중 어떤 걸 선택했는지, <input> 태그에는 어떤게 들어갔는지 매개변수로 넘길 수 있어야 합니다.

 

각각의 필요한 곳마다 name, value 를 추가 합니다.

그리고, 검색을 하게 되면, 화면에 보여질 게시글 수와 페이지 넘버가 필요하겠죠? "hidden" 을 이용합니다.

이제, 컨트롤러로 넘어갈 때, searchName , searchType, pageNum, amount 를 받아주면 되는데, 이전 글에서 사용한 Criteria 에 같이 만들어 주겠습니다.

그러면 값은 잘 전달이 되겠고, 이제 Service , Mapper 의 getList, getTotal 을 수정해 주면 됩니다.

검색을 하게 된다면, 페이지네이션에 표기될 페이지 수도 바뀌겠죠?

 

Service, Mapper 의 getList, getTotal 이 cri 를 받을 수 있도록 수정 해줍시다. ( getList 는 이미 되어 있음 )

이제 mapper.xml 의 getList , getTotal 을 수정해주어야 하는데, SQL 문은 아래처럼 작성하면 됩니다.

빨간색 박스에 있는 WHERE 절이 저번 글에서 페이징 할 때 에 비해 추가되면 됩니다.

 

이 형태를 mapper.xml 에서는 아래와 같이 사용할 수 있습니다.

※ 마지막 if는 아무것도 입력하지 않고, 검색을 눌렀을 경우

if 문의 문자열 '%' 와 #{searchName} 을 같이 사용하기 위해서 searchName 앞뒤로 || 를 사용 해주어야 합니다.

 

이런식으로, getTotal 도 아래처럼 바꿔주어야 합니다.

 

이렇게 변경을 해주었다면, 컨트롤러 에서는 아래와 같이 사용 합니다.

 

그리고, view 에서의 처리를 해주면 되는데....

검색을 하게 되면, 페이지네이션도 바뀌어야 하고, 다음 페이지 ( 2, 3, 4 .... ) 등을 눌렀을 때도, 검색에 관련된 searchType, searchName 을 들고 있어야 하기 때문에, hidden 을 이용합니다.

또한, dataset 을 이용해서 클릭한 pageNum 을 바꿔서 컨트롤러로 넘겨주어야 합니다.

<form action="freeList" name ="pageForm" method="post">
  <div class="text-center">
    <hr>

    <ul class="pagination pagination-sm">

      <!-- 2. 이전페이지 활성화여부 -->
      <c:if test="${pageVO.prev }">
          <li><a href="#" data-pagenum='${pageVO.startPage - 1 }'>이전</a></li>
      </c:if>

      <!-- 1. 페이지네이션 처리 -->
      <c:forEach var="num" begin="${pageVO.startPage }" end="${pageVO.endPage }">
          <li class="${pageVO.pageNum eq num ? 'active' : ''}">
              <a href="#" data-pagenum='${num }'>${num }</a>
          </li>
      </c:forEach>

      <!-- 3. 다음버튼 활성화여부 -->
      <c:if test="${pageVO.next }">
          <li><a href="#" data-pagenum='${pageVO.endPage + 1 }'>다음</a></li>
      </c:if>
    </ul>

    <button type="button" class="btn btn-info" onclick="location.href='freeRegist'">글쓰기</button>
  </div>

  <input type="hidden" name="pageNum" value="${pageVO.cri.pageNum }">
  <input type="hidden" name="amount" value="${pageVO.cri.amount }">
  <input type="hidden" name="searchType" value="${pageVO.cri.searchType }">
  <input type="hidden" name="searchName" value="${pageVO.cri.searchName }">

</form>

<script>
//		페이지 처리
//      모든 a버튼을 눌렀을 때 a가 가지고 있는 pageNum값을 가지고 form태그로 이동하도록 처리
//      동적쿼리 이용해서 sql문 변경
//      화면에 검색키워드가 미리 남겨지도록 처리.
  var pagination = document.querySelector(".pagination");
  pagination.onclick = function() {
    event.preventDefault(); // 고유이벤트 속성 중지
    if(event.target.tagName != 'A') return;

    // 사용자가 클릭한 페이지 번호를 form에 넣고 서브밋을 보냅니다.
    document.pageForm.pageNum.value = event.target.dataset.pagenum;
    document.pageForm.submit(); // 서브밋
  }

  window.onload = function() {
    if(history.state == '') return; // 메시지를 출력했다면 함수종료

    var msg = '<c:out value="${msg }" />';

    if(msg != ''){
      alert(msg);
      // 기존 기록을 삭제하고 새로운 기록을 추가 ( 이렇게 변경된 값은 history.state로 데이터를 확인가능 )
      history.replaceState('', null, null); // 브라우저 기록컨트롤 (추가할데이터, 제목, url주소)
      // console.log(history.state);
    }
  }
</script>

위의 처리를 다 헀다면, 검색창에는 이 전에 검색한 타입, 검색한 내용을 가지고 있도록 아래처럼 작성해 줍니다.

여기까지 간단하게 게시판 검색 기능을 만들어 보았는데요, 나중에 테이블이 복잡해지고, 조인이 들어가게 되면 얼마나 머리가 아플지 벌써부터 걱정이 듭니다 ㅎㅎㅎㅎㅎ

 

※ 검색 기능까지 할 수 있다면, 1인분 + a 라고 합니다.