프로젝트

17. 공지사항 게시판 (검색)

하차모 2023. 5. 30. 22:32

게시글 키워드 검색

 

기능을 추가할 때마다 UI가 계속 바뀐다.

이번에는 게시글 목록 우측 상단에 검색 태그를 추가했다.

 

 

notice_list.html

<form action="/notice/list" method="get" id="noticeForm">
	<div class="input-group" style="width: 20rem;">
		<select class="form-select" name="searchBoardVO.searchSelect">
		  <option value="BOARD_TITLE" 
		  		th:selected="${boardVO.searchBoardVO == null or (boardVO.searchBoardVO != null and boardVO.searchBoardVO.searchSelect == 'BOARD_TITLE')}">제목</option>
		  <option value="ENAME"
		  		th:selected="${boardVO.searchBoardVO != null and boardVO.searchBoardVO.searchSelect == 'ENAME'}">작성자</option>
		</select>
		<input type="text" class="form-control w-25" name="searchBoardVO.searchKeyword"
				th:value="${boardVO.searchBoardVO == null ? '' : boardVO.searchBoardVO.searchKeyword}">
		<input type="submit" class="btn" value="검색">
	</div>
</form>

검색 기능이기 때문에 form 데이터를 get 방식으로 처리했다.

GET 방식은 클라이언트에서 서버로 데이터를 전송할 때 URL에다 ‘?변수 이름=값’ 형태로 데이터를 넣어 전송한다. (Query String 형식)

POST 방식은 HTTP 패킷의 body 부분에 그 값을 넣어서 전송한다. URL로는 데이터가 노출되지 않기 때문에 보안에 더 우수하다.

 

GET 방식은 검색이나 조회 등 데이터를 읽을 때,

POST 방식은 게시, 수정 등 데이터를 생성할 때 사용한다.

 

 

네이버 검색 form 태그를 확인해보면 get 방식인 것을 알 수 있다.

 

 

키워드 검색 기능에서 필요한 데이터는 ‘검색유형’과 ‘검색 키워드’이다. (검색 유형에는 제목, 작성자가 있다.)

 

사용자가 select 태그에서 고른 option의 value값이 바로 쿼리로 들어가도록 테이블의 컬럼 이름으로 넣었다.(제목=”BOARD_TITLE”, 작성자=”ENAME”)

 

 

SearchBoardVO.java

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class SearchBoardVO {
	private String searchSelect;
	private String searchKeyword;
}

BoardVO.java

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class BoardVO {
	
	...(생략)
	
	private SearchBoardVO searchBoardVO;
	
}

SearchBoardVO를 만들고 BoardVO의 변수로 추가한다.

 

 

NoticeController.java

//게시판 목록
@GetMapping("/list")
public String noticeList(Model model, BoardVO boardVO) {

    //전체 글 목록 조회
    model.addAttribute("noticeList", noticeService.getNoticeList(boardVO));

    //중요글 목록 조회
    model.addAttribute("noticeImportantList", noticeService.getNoticeImportantList());

    return "content/notice/notice_list";
}

form태그 submit 해서 넘어온 값이 boardVO에 담겨지고, 전체 글 목록을 조회하는 쿼리에 파라메터로 넘어간다.

 

 

 

board-mapper.xml

<!-- 공지사항 글 목록 조회 -->
<select id="getNoticeList" resultMap="board">
	SELECT BOARD_NUM
	    , BOARD_TITLE
	    , BOARD_WRITER
	    , TO_CHAR(BOARD_DATE, 'YYYY-MM-DD') BOARD_DATE
	    , BOARD_VIEW
	    , ENAME
	    , (SELECT COUNT(FILE_NUM) 
			FROM BOARD_FILE
			WHERE BOARD_NUM = BOARD.BOARD_NUM) FILE_CNT
		, (SELECT COUNT(REPLY_NUM)
              FROM BOARD_REPLY
              WHERE BOARD_NUM = BOARD.BOARD_NUM) REPLY_CNT
	FROM BOARD, EMP
	WHERE BOARD_MENU_CODE = 'BOARD_MENU_001'
	AND BOARD_STATUS = 1
	AND BOARD_WRITER = EMPNO
	<if test='searchBoardVO != null and !searchBoardVO.searchKeyword.equals("")'>
	AND UPPER(${searchBoardVO.searchSelect}) LIKE '%'||UPPER(#{searchBoardVO.searchKeyword})||'%'
	</if>
	ORDER BY BOARD_NUM DESC
</select>

<if>문을 사용해 searchBoardVO가 Null 값이 아닐 때(사용자가 검색 버튼을 눌러 form 태그가 submit 되었을 때) WHERE 절이 실행되도록 했다.

 

#{}는 파라메터가 String 형태로 들어와 ‘파라메터’ 형태가 되고,

${}는 파라메터가 ‘’ 없이 바로 출력된다. (테이블이나 컬럼명을 파라메타로 전달할 때 사용된다)

컬럼명을 담고 있는 searchSelect는 ${}를, 검색 키워드를 담고 있는 searchKeyword는 #{}를 사용했다.

 

 

해당 쿼리로 조회된 리스트가 noticeList라는 이름으로 html에 넘어간다.