[Spring] 게시판 검색어 기능
페이징 처리가 된 게시판에 검색어 기능을 추가
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>