08_Spring_240422(월)_68일차(2) - ★BoardProject★ - 10. 게시판 - 게시글 목록 조회

soowagger·2024년 4월 22일

8_Spring

목록 보기
25/38

10-2) 게시글 목록 조회

BoardController

@Controller
@RequestMapping("board")
@Slf4j
@RequiredArgsConstructor
public class BoardController {
	
	private final BoardService service;
	
	/** 게시글 목록 조회
	 * @param boardCode : 게시판 종류 구분 번호
	 * @param cp : 현재 조회를 요청한 페이지 (없으면 1)
	 * @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) {
		
		log.debug("bodeCode : " + boardCode);
		
		// 조회 서비스 호출 후 결과 반환
		Map<String, Object> map = service.selectBoardList(boardCode, 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> selectBoardList(int boardCode, int cp) {
	
	// 1. 지정된 게시판(boardCode)에서
	//    삭제되지 않은 게시글 수를 조회
	int listCount = mapper.getListCount(boardCode);
	
	
	// 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.selectBoardList(boardCode, 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="getListCount">
	SELECT COUNT(*)
	FROM "BOARD"
	WHERE BOARD_DEL_FL = 'N'
	AND BOARD_CODE = #{boardCode}
</select>

<!--
	<![CDATA["문자열"]]> - 해당 태그 내부에 작성된 문자열은 특수 기호로 해석하지 말고
	문자(Character) 그대로 인식하는 태그 (순수 문자 데이터임을 지정)  
-->
<!-- 특정 게시판의 지정된 페이지 목록 조회 -->
<select id="selectBoardList">
	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}
	ORDER BY BOARD_NO DESC
</select>

boardList.html 일부

<section class="board-list">
			<th:block th:each="boardType : ${application.boardTypeList}">
				<h1 class="board-name"
					th:if="${boardType.boardCode} == ${boardCode}"
					th:text="${boardType.boardName}"
				>게시판 이름</h1>
			</th:block>
			
			<div class="list-wrapper">
				<table class="list-table">

					<thead>
						<tr>
							<th>글번호</th>
							<th>제목</th>
							<th>작성자</th>
							<th>작성일</th>
							<th>조회수</th>
							<th>좋아요</th>
						</tr>
					</thead>

					<tbody>
						<!-- 게시글이 존재하지 않을 때 -->
						
						<!-- 여러 행 조회 시 결과가 없을 경우 == List가 비어있음 -->
						
						<!-- #lists : 타임리프에서 list 관련 기능을 제공하는 객체 -->
						<!-- ${#lists.size(boardList) == 0} -->
						<th:block th:if="${#lists.isEmpty(boardList)}">
							<tr>
								<th colspan="6">게시글이 존재하지 않습니다.</th>
							</tr>
						</th:block>

						<!-- 게시글이 존재할 때 -->
						<th:block th:unless="${#lists.isEmpty(boardList)}">
							
							<tr th:each="board : ${boardList}" th:object="${board}">
									
								<td th:text="*{boardNo}">게시글 번호</td>
								
								<td>
									<!-- 썸네일 추가 예정 -->
	
									<a th:text="*{boardTitle}">게시글 제목</a>
									
									<th:block th:text="|[*{commentCount}]|">댓글 수</th:block>
								</td>
	
								<!-- 작성자 닉네임 -->
								<td th:text="*{memberNickname}">닉네임</td>
	
								<!-- 작성일 -->
								<td th:text="*{boardWriteDate}">2023-10-26</td>
	
								<!-- 조회수 -->
								<td th:text="*{readCount}">0</td>
	
								<!-- 좋아요 수 -->
								<td th:text="*{likeCount}">0</td>
							</tr>
						</th:block>

					</tbody>
				</table>
			</div>



			<div class="btn-area">
				<!-- 로그인 상태일 때만 글쓰기 버튼 노출 -->
				<button id="insertBtn">글쓰기</button>
			</div>


			<!-- ============================================================================================================== -->

			<!-- 게시글이 있을 때만 페이지네이션이 보이게 할 예정 -->
			<div class="pagination-area">

				<ul class="pagination" th:object="${pagination}">

					<!-- 첫 페이지로 이동 -->
					<li><a th:href="@{/board/{boardCode}(boardCode=${boardCode}, cp=1)}">&lt;&lt;</a></li>

					<!-- 이전 목록 마지막 번호로 이동 -->
					<li><a th:href="@{/board/{boardCode}(boardCode=${boardCode}, cp=*{prevPage})}">&lt;</a></li>

					<!-- 특정 페이지로 이동 -->
					<th:block th:each="i : *{#numbers.sequence(startPage, endPage)}">
						
						<!-- 현재 보고 있는 페이지 -->
						<li th:if="${i} == *{currentPage}">
							<a class="current" th:text="${i}">현재페이지</a>
						</li>
	
						<!-- 보고있지 않은 페이지 -->
						<li th:unless="${i} == *{currentPage}">
							<a th:href="@{/board/{boardCode}(boardCode=${boardCode}, cp=${i})}" 
							th:text="${i}">이동할 페이지</a>
						</li>
						
					</th:block>
					
					<!-- 다음 목록 시작 번호로 이동 -->
					<li><a th:href="@{/board/{boardCode}(boardCode=${boardCode}, cp=*{nextPage})}">&gt;</a></li>

					<!-- 끝 페이지로 이동 -->
					<li><a th:href="@{/board/{boardCode}(boardCode=${boardCode}, cp=*{maxPage})}">&gt;&gt;</a></li>
				</ul>
			</div>

profile

0개의 댓글