Spring

[Spring] 게시판 검색어 기능

jane.dev 2021. 9. 26. 22:36
반응형

페이징 처리가 된 게시판에 검색어 기능을 추가

2021.09.24 - [Spring] - [Spring] 게시판 페이징(Paging) 처리

 

[Spring] 게시판 페이징(Paging) 처리

테이블에서 데이터 List를 가져오는 쿼리문을 페이징 처리가 가능하도록 작성 테이블 구조(Oracle) CREATE SEQUENCE board_num; CREATE TABLE board_tbl( bno NUMBER(10, 0), title VARCHAR2(200) NOT NULL, conte..

wheneveryouwantsz.tistory.com

 

기존에 생성한 Criteria 객체(페이지에 대한 정보)를 상속한 SearchCriteria 객체를 생성

@Data
public class SearchCriteria extends Criteria{
    private String searchType;	// 검색어를 조회하는 타입(제목, 본문, 글쓴이)
    private String keyword;	// 검색어를 조회하는 키워드
}

 

Controller에서는 Criteria를 사용하던 파라미터를 SearchCriteria 로 변경

@GetMapping("/list")
public void list(SearchCriteria cri, Model model){
    List<BoardVO> board = service.getListPaging(cri);
    model.addAttribute("board", board);
    PageDTO dto = new PageDTO(cri, 전체 데이터개수, 페이지당 글 개수);
    model.addAttribute("dto", dto);
}

 

Controller에서 로직이 실행되고 이동하는 list.jsp

2021.09.29 - [Spring] - [spring] select 태그를 이용해 데이터 삽입시 텍스트 대치

 

[spring]

 

<select> 태그 내부의 <option> 태그로 검색 조건을 작성

<form>
    <select name="searchType">
    	<option value="n"
        <c:out value="${dto.cri.searchType == null ? 'selected' : '' }"/>>
        -
        </option>
        <option value="t"
        <c:out value="${dto.cri.searchType eq 't' ? 'selected' : '' }"/>>
        제목
        </option>
        <option value="c"
        <c:out value="${dto.cri.searchType eq 'c'  ? 'selected' : '' }"/>>
        본문
        </option>
        <option value="w"
        <c:out value="${dto.cri.searchType eq 'w' ? 'selected' : '' }"/>>
        글쓴이
        </option>
        <option value="tc"
        <c:out value="${dto.cri.searchType eq 'tc' ? 'selected' : '' }"/>>
        제목 + 본문
        </option>
        <option value="cw"
        <c:out value="${dto.cri.searchType eq 'cw' ? 'selected' : '' }"/>>
        본문 + 글쓴이
        </option>
        <option value="tcw"
        <c:out value="${dto.cri.searchType eq 'tcw' ? 'selected' : '' }"/>>
        제목 + 본문 + 글쓴이
        </option>
    </select>
    <input type="text" name="keyword" value="${dto.cri.keyword }" placeholder="검색창"/>
    <input type="submit" value="search"/>
</form>

c:out의 value 속성에는 출력할 값이 입력되어야함
해당 페이지에서 옵션 메뉴를 지정하고 <input> 태그의 submit 버튼을 누르면 페이지 이동이 일어나고

SearchCriteria의 searchType 값이 DB에 삽입

→ 다시 해당페이지로 돌아왔을 때, selected 값이 출력된 상태이기 때문에 해당 옵션메뉴를 default 값으로 볼 수 있음

값(value)   의미
n null 검색 조건 없음
t title 제목에 검색어 포함시 리스팅
c content 본문에 검색어 포함시 리스팅
w writer 글쓴이에 검색어 포함시 리스팅
tc title + content 제목과 본문에 검색어 포함시 리스팅
cw content + writer 본문과 글쓴이에 검색어 포함시 리스팅
tcw title + content + writer 제목과 본문, 글쓴이에 검색어 포함시 리스팅

 

 url 파라미터값을 작성해 페이지가 이동해도 검색어 조건이 유지될 수 있도록 수정(list.jsp)

<!-- 이전 버튼 -->
<a class="page-link" 
   href="/board/list?pageNum=${dto.startPage - 1 }
         &searchType=${dto.cri.searchType}
         &keyword=${dto.cri.keyword}">
   Previous
</a>

<!-- 번호 버튼 -->
<a class="page-link" 
   href="/board/list?pageNum=${pageNum }
         &searchType=${dto.cri.searchType}
         &keyword=${dto.cri.keyword}">
   ${pageNum }
</a>

<!-- 다음 버튼 -->
<a class="page-link" 
    href="/board/list?pageNum=${dto.endPage + 1 }
          &searchType=${dto.cri.searchType}
          &keyword=${dto.cri.keyword}">
    Next
</a>

 

Mapper 와 Service 메서드의 파라미터에 작성된 Criteria 객체는 SearchCriteria로 변경

Mapper.xml 쿼리문 수정 및 추가

<sql id="search">
	<if test="searchType != null">
		<if test="searchType == 't'.toString()">
			(title LIKE '%'||#{keyword}||'%') AND
		</if>
		<if test="searchType == 'c'.toString()">
			(content LIKE '%'||#{keyword}||'%') AND
		</if>
		<if test="searchType == 'w'.toString()">
			(writer LIKE '%'||#{keyword}||'%') AND
		</if>
		<!-- 두개 이상의 조건절은 괄호로 묶어서 작성 -->
		<if test="searchType == 'tc'.toString()">
			((title LIKE '%'||#{keyword}||'%') 
			OR 
			content LIKE ('%'||#{keyword}||'%')) AND
		</if>
		<if test="searchType == 'cw'.toString()">
			((content LIKE '%'||#{keyword}||'%') 
			OR 
			(writer LIKE '%'||#{keyword}||'%')) AND
		</if>
		<if test="searchType == 'tcw'.toString()">
			((title LIKE '%'||#{keyword}||'%') 
			OR 
			(content LIKE '%'||#{keyword}||'%') 
			OR 
			(writer LIKE '%'||#{keyword}||'%')) AND
		</if>
	</if>
</sql>

동적 SQL 엘리먼트 작성

1. 기존 쿼리문 WHERE절에 넣어 조건을 추가할 수 있도록 AND 를 작성

2. 하나의 LIKE 조건절을 괄호 내부에 넣어 작성

 

<mapper namespace="mapper인터페이스 경로.Mapper">
  <select id="getListPaging" resultType="VO객체 경로.BoardVO">
    <![CDATA[
      SELECT bno, title, content, writer, regdate, updatedate FROM
      (SELECT /*+ INDEX_DESC(board_tbl pk_board) */
      rownum rn, board_tbl.* FROM board_tbl 
      WHERE      
    ]]>
    <include refid="search"</include>
    <![CDATA[
             rownum <= 페이지 번호 * 보여줄 글 개수) tbl
      WHERE rn > (페이지 번호 - 1) * 보여줄 글 개수
    ]]>
  </select>
</mapper>

기존 쿼리문이 검색어 조건을 지정하지 않았을 때도 작동되어야함

 

마지막으로 리스트를 작성한 테이블 내부에서 글제목을 클릭하면 해당 게시글의 상세페이지로 이동하는 경로에도

파라미터 값에 검색조건을 추가해 작성(list.jsp)

<c:forEach items="${list }" var="list">
    <tr>
        <td>${list.bno }</td>
        <!-- board/list 에서 board/get으로 이동 -->
        <td><a href="/board/get?bno=${board.bno }
                     &pageNum=${dto.cri.pageNum }
                     &searchType=${dto.cri.searchType}
                     &keyword=${dto.cri.keyword}">${board.title }</a></td>
        <td>${board.content }</td>
        <td>${board.writer }</td>
        <td>${board.regdate }</td>
        <td>${board.updatedate }</td>
    </tr>
</c:forEach>