이전에 구현한 게시글 목록 조회에 참고해서 추가 기능을 넣어 볼 예정이다 .
<%-- 검색을 진행한 경우 파라미터 (key,query)를
쿼리스트링 태로 저장한 변수 --%>
<c:if test="${!empty param.key}" >
<c:set var="search" value="&key=${param.key}&query=${param.query}"/>
</c:if>
<div class="pagination-area">
<ul class="pagination">
<!-- 첫 페이지로 이동 -->
<li><a href="/board/${boardCode}?cp=1${search}"><<</a></li>
<!-- 이전 목록 마지막 번호로 이동 -->
<li><a href="/board/${boardCode}?cp=${pagination.prevPage}${search}"><</a></li>
<!-- 특정 페이지로 이동 -->
<c:forEach var="i" begin="${pagination.startPage}"
end="${pagination.endPage}" step="1">
<c:choose>
<c:when test="${i== pagination.currentPage}">
<!-- 현재 보고있는 페이지 -->
<li><a class="current">${i}</a></li>
</c:when>
<c:otherwise>
<!-- 현재 페이지를 제외한 나머지 -->
<li><a href="/board/${boardCode}?cp=${i}${search}">${i}</a></li>
</c:otherwise>
</c:choose>
</c:forEach>
<!-- 다음 목록 시작 번호로 이동 -->
<li><a href="/board/${boardCode}?cp=${pagination.nextPage}${search}">></a></li>
<!-- 끝 페이지로 이동 -->
<li><a href="/board/${boardCode}?cp=${pagination.maxPage}${search}">>></a></li>
</ul>
</div>
<!-- 검색창 -->
<form action="${boardCode}" method="get" id="boardSearch">
<select name="key" id="searchKey">
<option value="t">제목</option>
<option value="c">내용</option>
<option value="tc">제목+내용</tion>
<option value="w">작성자</option>
</select>
<input type="text" name="query" id="searchQuery" placeholder="검색어를 입력해주세요.">
<button>검색</button>
</form>
// 검색창 이전의 기록 남겨 놓기
const boardSearch = document.querySelector("#boardSearch");
const searchKey = document.querySelector("#searchKey");
const searchQuery = document.querySelector("#searchQuery");
const options = document.querySelectorAll("#searchKey > option");
(()=>{
const params = new URL(location.href).searchParams;
const key = params.get("key"); //t,c,tc,w중 하나
const query = params.get("query"); // 검색어
if(key != null){ // 검색을 했을 때
searchQuery.value=query; // 검색어를 화면에 출력
// option태그를 하나씩 순차접근해서 value가 key랑 같으면
// selected속성 추가
for(let op of options){
if(op.value == key){
op.selected = true;
}
}
}
})();
//검색어 없이 제출된 경우
boardSearch.addEventListener("submit", e =>{
if(searchQuery.value.trim().length == 0){
e.preventDefault();
location.pathname//해당게시판 1페이지로 이동
//location.pathname : 쿼리스트링을 제외한 실제 주소
}
})
if문으로 게시글 검색이 있을 경우와 없을 경우를 만들어 주었다
//게시글 목록 조회
@GetMapping("/{boardCode:[0-9]+}") // boardCode는 1자리 이상 숫자
public String selectBoardList(@PathVariable("boardCode") int boardCode
, @RequestParam(value="cp", required = false, defaultValue = "1") int cp
, Model model
, @RequestParam Map<String, Object> paramMap //파라미터가 전부다 담겨 있음
) {
// boardCode 확인
//System.out.println("boardCode: "+ boardCode);
if( paramMap.get("key") == null ) {//검색어가 없을 때
// 게시글을 목록 조회하는 service호출
Map<String, Object> map = service.selectBoardList(boardCode, cp);
//조회 결과를 request scope에 세팅 후 forward
model.addAttribute("map", map);
}else { //검색어가 있다 (검색 O)
paramMap.put("boardCode", boardCode);
Map<String , Object> map = service.selectBoardList(paramMap, cp);
model.addAttribute("map", map);
}
return "board/boardList";
}
/** 검색어를 통한 게시글 목록 조회(검색)
* @param paramMap
* @param cp
* @return boardList
*/
Map<String, Object> selectBoardList(Map<String, Object> paramMap, int cp);
매개변수의 자료형이 달라서 overlodding되어 메소드 사용할 수 있다!
// 게시글 목록 조회 (검색)
@Override
public Map<String, Object> selectBoardList(Map<String, Object> paramMap, int cp) {
// 1. 특정 게시판에 삭제되지 않고 검색 조건이 일치하는 게시글 수 조회
int listCount = dao.getListCount(paramMap);
// 2. 1번 조회 결과 + cp를 이용해서 Pagination 객체 생성
// -> 내부에 필드가 모두 계산 되어서 초기화 됨
Pagination pagination = new Pagination(cp, listCount);
// 3. 특정게시판에서
// 현재 페이지에 해당하는 게시글 목록 조회
// + 단, 검색 조건이 일치하는 글만
List<Board> boardList = dao.selectBoardList(pagination, paramMap);
// 4. paginatio, boardList를 Map에 담아서 반환
Map<String, Object> map = new HashMap<String, Object>();
map.put("pagination", pagination);
map.put("boardList", boardList);
return map;
}
/** 게시글 수 조회(검색)
* @param paramMap
* @return listCount
*/
public int getListCount(Map<String, Object> paramMap) {
return sqlSession.selectOne("boardMapper.getListCount_search", paramMap);
}
/** 게시글 목록 조회(검색)
* @param pagination
* @param paramMap
* @return boardList
*/
public List<Board> selectBoardList(Pagination pagination, Map<String, Object> paramMap) {
// 1) offset 계산
int offset
= (pagination.getCurrentPage() -1) * pagination.getLimit();
// 2) Row Bounds객체 생성
RowBounds rowBounds = new RowBounds(offset, pagination.getLimit());
// 3) selectList("namespace.id", 파라미터, Rowbounds)호출
return sqlSession.selectList("boardMapper.selectBoardList_search", paramMap, rowBounds);
}
동적 SQL사용을 사용하여 조회해 보았다(if, choose,CDATA)
<!-- 특정게시판에 삭제되지 않고 검색 조건에 일치하는 게시글 수 조회 -->
<select id="getListCount_search" resultType="_int">
SELECT COUNT(*)
FROM BOARD
<!-- 작성자 검색일 경우 -->
<if test='key=="w"'>
JOIN MEMBER USING(MEMBER_NO)
</if>
WHERE BOARD_DEL_FL = 'N'
AND BOARD_CODE = #{boardCode}
<choose>
<when test='key== "t"'>
<!-- 제목 -->
AND BOARD_TITLE LIKE '%${query}%'
</when>
<when test='key=="c"'>
<!-- 내용 -->
AND BOARD_CONTENT LIKE '%${query}%'
</when>
<when test='key=="tc"'>
<!-- 제목 + 내용 -->
AND (BOARD_TITLE LIKE '%${query}%' OR BOARD_CONTENT LIKE '%${query}%')
</when>
<when test='key=="w"'>
<!-- 작성자(닉네임) -->
AND MEMBER_NICKNAME LIKE '%#{query}%'
</when>
</choose>
</select>
<!-- CDATA 태그 : 해당 태그 내부에 작성된 것은 모두 문자로 취급-->
<!-- 게시글 목록 조회 -->
<select id="selectBoardList_search" resultMap="board_rm">
SELECT BOARD_NO, BOARD_TITLE, MEMBER_NICKNAME, READ_COUNT,
<![CDATA[
CASE
WHEN SYSDATE - B_CREATE_DATE < 1/24/60
THEN FLOOR( (SYSDATE - B_CREATE_DATE) * 24 * 60 * 60 ) || '초 전'
WHEN SYSDATE - B_CREATE_DATE < 1/24
THEN FLOOR( (SYSDATE - B_CREATE_DATE) * 24 * 60) || '분 전'
WHEN SYSDATE - B_CREATE_DATE < 1
THEN FLOOR( (SYSDATE - B_CREATE_DATE) * 24) || '시간 전'
ELSE TO_CHAR(B_CREATE_DATE, 'YYYY-MM-DD')
END B_CREATE_DATE,
]]>
(SELECT COUNT(*) FROM "COMMENT" C
WHERE C.BOARD_NO = B.BOARD_NO) COMMENT_COUNT,
(SELECT COUNT(*) FROM BOARD_LIKE L
WHERE L.BOARD_NO = B.BOARD_NO) LIKE_COUNT,
(SELECT IMG_PATH || IMG_RENAME FROM BOARD_IMG I
WHERE I.BOARD_NO = B.BOARD_NO
AND IMG_ORDER = 0) THUMBNAIL
FROM "BOARD" B
JOIN "MEMBER" USING(MEMBER_NO)
WHERE BOARD_DEL_FL = 'N'
AND BOARD_CODE = #{boardCode}
<choose>
<when test='key== "t"'>
<!-- 제목 -->
AND BOARD_TITLE LIKE '%${query}%'
</when>
<when test='key=="c"'>
<!-- 내용 -->
AND BOARD_CONTENT LIKE '%${query}%'
</when>
<when test='key=="tc"'>
<!-- 제목 + 내용 -->
AND (BOARD_TITLE LIKE '%${query}%' OR BOARD_CONTENT LIKE '%${query}%')
</when>
<when test='key=="w"'>
<!-- 작성자(닉네임) -->
AND MEMBER_NICKNAME LIKE '%#{query}%'
</when>
</choose>
ORDER BY BOARD_NO DESC
</select>