08_Spring_240501(수)_75일차(0) - ★BoardProject★ - 17. 게시글 검색

soowagger·2024년 5월 1일

8_Spring

목록 보기
32/38

17. 게시글 검색

boardList.html 검색창 부분 경로 설정 및 name값 확인

BoardController 게시글 목록 조회 메서드 수정

/** 게시글 목록 조회 + 검색
 * @param boardCode : 게시판 종류 구분 번호
 * @param cp : 현재 조회를 요청한 페이지 (없으면 1)
 * @param paramMap : 제출된 파라미터가 모두 저장된 Map
 * 					(검색 시 key, query 담겨 있음)
 * @return
 * 
 * - /board/xxx
 *   /board 이하 1레벨 자리에 숫자로 된 요청 주소가
 *   작성되어 있을 때만 동작 -> 정규표현식 이용
 * 
 * [0-9] : 한 칸에 0~9 사이 숫자 입력 가능
 * + : 하나 이상
 * 
 * [0-9]+ : 모든 숫자
 */
@GetMapping("{boardCode:[0-9]+}")
public String selectBoardList(@PathVariable("boardCode") int boardCode,
							@RequestParam(value="cp", required = false, defaultValue = "1") int cp,
							Model model,
							@RequestParam Map<String, Object> paramMap) {
	
	log.debug("bodeCode : " + boardCode);
	
	// 조회 서비스 호출 후 결과 반환
	Map<String, Object> map = null; 
	
	// 검색이 아닌 경우 --> paramMap은 {}
	if(paramMap.get("key") == null) {
		
		// 게시글 목록 조회 서비스 호출
		map = service.selectBoardList(boardCode, cp);
		
	} else { // 검색인 경우 --> paramMap은 {key=t, query=검색어}
		
		// boardCode를 paramMap에 추가
		paramMap.put("boardCode", boardCode);
		// -> paramMap은 {key=t, query=검색어, boardCode=1}
		
		// 검색 서비스 호출
		map = service.searchList(paramMap, cp);
		
	}
			
	
	model.addAttribute("pagination", map.get("pagination"));
	model.addAttribute("boardList", map.get("boardList"));
	
	return "board/boardList"; // boardList.html로 forward
} 

BoardServiceImpl(게시글 목록 조회 참고)

// * 게시글 검색 서비스 (게시글 목록 조회 참고)
@Override
public Map<String, Object> searchList(Map<String, Object> paramMap, int cp) {
	
	// paramMap (key, query, boardCode)
	
	
	// 1. 지정된 게시판(boardCode)에서
	//	  검색 조건에 맞으면서
	//    삭제되지 않은 게시글 수를 조회
	int listCount = mapper.getSearchCount(paramMap);
	
	
	// 2. 1번의 결과 + cp를 이용해서
	//    Pagination 객체를 생성
	// * Pagination 객체 : 게시글 목록 구성에 필요한 값을 저장한 객체
	Pagination pagination = new Pagination(cp, listCount);
	
	
	// 3. 특정 게시판의 지정된 페이지 목록 조회
	/* ROWBOUNDS 객체 (MyBatis 제공 객체)
	 * - 지정된 크기(offset)만큼 건너뛰고 
	 * - 제한된 크기(limit)만큼의 행을 조회하는 객체
	 * 
	 * --> 페이징 처리가 굉장히 간단해짐!
	 */
	
	int limit = pagination.getLimit();
	int offset = (cp - 1) * limit;
	RowBounds rowBounds = new RowBounds(offset, limit);
	
	/* Mapper 메서드 호출 시
	 * - 첫 번째 매개변수 -> SQL에 전달할 파라미터
	 * - 두 번째 매개변수 -> RowBounds 객체 전달
	 *
	 */
	List<Board> boardList = mapper.selectSearchList(paramMap, rowBounds);
	
	
	// 4. 목록 조회 결과 + Pagination 객체를 Map으로 묶음
	Map<String, Object> map = new HashMap<>();
	
	map.put("pagination", pagination);
	map.put("boardList", boardList);
	
	// 5. 결과 반환
	return map;
}

board-mapper.xml

<!-- 검색 조건이 맞는 게시글 수 조회 -->
<select id="getSearchCount">
	SELECT COUNT(*)
	FROM "BOARD"
	
	<!-- 작성자 검색인 경우 -->
	<if test='key=="w"'>
		JOIN "MEMBER" USING(MEMBER_NO)
	</if>
	
	WHERE BOARD_DEL_FL = 'N'
	AND BOARD_CODE = #{boardCode}
	
	<choose>
		<!-- 제목 검색 (key 값이 "t"인 경우)-->
		<when test='key=="t"'>
			AND BOARD_TITLE LIKE '%' || #{query} || '%'
		</when>
		
		<!-- 내용 검색 (key 값이 "c"인 경우)-->
		<when test='key=="c"'>
			AND BOARD_CONTENT LIKE '%' || #{query} || '%'
		</when>
		
		<!-- 제목 + 내용 검색 (key 값이 "tc"인 경우)-->
		<when test='key=="tc"'>
			AND (
				BOARD_CONTENT LIKE '%' || #{query} || '%'
				OR
				BOARD_TITLE LIKE '%' || #{query} || '%'
				) 
		</when>
		
		<!-- 작성자 검색 (key 값이 "w"인 경우 -->
		<otherwise>
			AND MEMBER_NICKNAME LIKE '%' || #{query} || '%'
		</otherwise>
		
	</choose>
	
</select>


<!-- 검색 결과 목록 조회 -->
<select id="selectSearchList">
	SELECT BOARD_NO, BOARD_TITLE, MEMBER_NICKNAME, READ_COUNT,

	    (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,
    
	    <![CDATA[
	    CASE
		    WHEN SYSDATE - BOARD_WRITE_DATE < 1 / 24 / 60
		    THEN FLOOR((SYSDATE - BOARD_WRITE_DATE) * 24 * 60 * 60) || '초 전'
		    
		    WHEN SYSDATE - BOARD_WRITE_DATE < 1 / 24
		    THEN FLOOR((SYSDATE - BOARD_WRITE_DATE) * 24 * 60) || '분 전'
		    
		    WHEN SYSDATE - BOARD_WRITE_DATE < 1
		    THEN FLOOR((SYSDATE - BOARD_WRITE_DATE) * 24) || '시간 전'
		    
		    ELSE TO_CHAR(BOARD_WRITE_DATE, 'YYYY-MM-DD')
		    
		END BOARD_WRITE_DATE
    	]]>
	  
	FROM "BOARD" B
	JOIN "MEMBER" USING(MEMBER_NO)
	WHERE BOARD_DEL_FL = 'N'
	AND BOARD_CODE = #{boardCode}
	
	<choose>
		<!-- 제목 검색 (key 값이 "t"인 경우)-->
		<when test='key=="t"'>
			AND BOARD_TITLE LIKE '%' || #{query} || '%'
		</when>
		
		<!-- 내용 검색 (key 값이 "c"인 경우)-->
		<when test='key=="c"'>
			AND BOARD_CONTENT LIKE '%' || #{query} || '%'
		</when>
		
		<!-- 제목 + 내용 검색 (key 값이 "tc"인 경우)-->
		<when test='key=="tc"'>
			AND (
				BOARD_CONTENT LIKE '%' || #{query} || '%'
				OR
				BOARD_TITLE LIKE '%' || #{query} || '%'
				) 
		</when>
		
		<!-- 작성자 검색 (key 값이 "w"인 경우 -->
		<otherwise>
			AND MEMBER_NICKNAME LIKE '%' || #{query} || '%'
		</otherwise>
		
	</choose>
	
	ORDER BY BOARD_NO DESC
</select>

boardList.html 페이지네이션 출력 관련하여 분기 처리

profile

0개의 댓글