@Slf4j// log찍어보기 위한 어노테이션
@Controller // bean객체 등록! (servlet-context.xml 에서 확인가능!)
@SessionAttributes({"loginUser"})
@RequestMapping("/board")// 공통주소 설정(현재 컨트롤러 호출시 /spring/board의 경로로 들어오는 모든 url요청을 받아줌)
public class BoardController {
@Autowired
private BoardService boardService;
//${contextPath}/board/list/C // 리액트 => 변수명
@GetMapping("/list/{boardCode}") // 스프링 => 동적파라미터설정 : {변수명} => boardCode의 값을 받아 매핑
public String selectList(
@PathVariable("boardCode") String boardCode
// @PathVariable(변수명) : URL경로로 포함되어있는 값을 변수로 사용가능
// + PathVariable로 등록한 변수는 자동으로 requestScope에 저장된다.
, @RequestParam(value="currentPage", defaultValue = "1" ) int currentPage
, Model model
, @RequestParam Map<String, Object> paramMap //요청받은 값을 담아줄 예정
) {
paramMap.put("boardCode", boardCode);
log.info("paramMap = {}", paramMap);
// @Slf4j어노테이션으로 log찍어볼 수 있음. 2번째 인자값이 1번째 {}안에 값으로 출력됨
// 1) 게시글갯수 카운팅(페이징처리)
int listCount = boardService.selectListCount(paramMap);
int pageLimit = 10; // 페이징수
int boardLimit = 5; // 한 페이지에 보여질 게시글수
// 2) pageInfo 생성
PageInfo pi = Pagination.getPageInfo(listCount, currentPage, pageLimit, boardLimit);
// Pagination.java에 미리 생성해놓은 필드명들을 가져옴
// 3) 게시글 목록 조회
List<Board> list = boardService.selectList(pi, paramMap);
// 4) pageInfo, list, paramMap을 model에 추가(requestScope)
model.addAttribute("pi", pi);
model.addAttribute("list", list);
model.addAttribute("param", paramMap) ;
return "board/boardListView";
}
}
// boardmapper.mxl
// 1)boardWriter가 userNo값을 담고있기 때문에 MEMBER테이블과 JOIN하여 userName값 가져올 예정
// 2)WHERE절에 if문을 통해 검색내용이 있다면 검색한 keyword에 맞는 데이터들만 가져오기
<select id="selectList" parameterType="map" resultMap="boardResultSet">
SELECT BOARD_NO, BOARD_TITLE, BOARD_CONTENT, COUNT, CREATE_DATE,
ORIGIN_NAME, CHANGE_NAME, BOARD_CD, USER_NAME as BOARD_WRITER
FROM BOARD B
JOIN MEMBER M ON M.USER_NO = B.BOARD_WRITER
WHERE B.STATUS = 'Y'
AND BOARD_CD = #{boardCode}
<if test="keyword != null and keyword != ''">
AND
<choose>
<when test="condition == 'title'">
BOARD_TITLE LIKE '%${keyword}%'
</when>
<when test="condition.equals('content')">
BOARD_CONTENT LIKE '%' || #{keyword} || '%'
</when>
<when test="condition.equals('writer)">
USER_NAME LIKE CONCAT(CONCAT('%', #{keyword}), '%')
</when>
<when test="condition.equals('titleAndContent')">
(BOARD_TITLE LIKE '%${keyword}%'
OR
BOARD_CONTENT LIKE '%' || #{keyword} || '%')
</when>
</choose>
</if>
ORDER BY BOARD_NO DESC
</select>
// 게시글 출력하기
// boardListView.jsp
<div class="innerOuter" style="padding:5% 10%;">
<h2>일반게시판</h2>
<c:if test="${not empty loginUser} }" >
<a class="btn btn-secondeary" style="float:right" href="" >글쓰기</a>
</c:if>
<br>
<table id="boardList" class="table table-hover" align="center">
<thead>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<c:choose>
<c:when test="${empty list}">
// controller에서 model에 담은 "list"가 없다면
<tr>
<td colspan="5">게시글이 없습니다.</td>
</tr>
</c:when>
<c:otherwise>
// "list"를 boardList라는 변수명으로 DB의 데이터를 뿌려주기
<c:forEach var="boardList" items="${list}">
<tr>
<td>${boardList.boardNo}</td>
<td>${boardList.boardTitle}</td>
<td>${boardList.boardWriter}</td>
<td>${boardList.count}</td>
<td>${boardList.createDate}</td>
</tr>
</c:forEach>
</c:otherwise>
<tr>
<td colspan="5">게시글이 없습니다.</td>
</tr>
</c:otherwise>
</c:choose>
</tbody>
</table>
// 페이징처리 및 검색기능
// boardListView.jsp
<c:set var="url" value="?currentPage="></c:set> // 공통 url주소를 담음
<c:if test="${not empty param.condition}" >
<c:set var="searUrl" value="&condition=${param.condition}&keyword=${param.keyword}" />
</c:if>
<div id="pagingArea">
<ul class="pagination">
<c:if test="${pi.currentPage eq 1}"> // 1페이지일때
<li class="page-item">
<a class="page-link">Previous</a></li>
</c:if>
<c:if test="${pi.currentPage ne 1}"> // 1페이지가 아닐때만 보이게
<li class="page-item">
<a class="page-link" href="${url}${pi.currentPage-1}${searUrl}">Previous</a></li>
</c:if>
<c:forEach var='i' begin='${pi.startPage}' end='${pi.endPage}'>
<li class="page-item">
<a class="page-link" href="${url}${i}${searUrl}">[ ${i} ]</a></li>
</c:forEach>
<c:if test="${pi.currentPage eq pi.maxPage}"> // 마지막페이지일때
<li class="page-item">
<a class="page-link">Next</a></li>
</c:if>
<c:if test="${pi.currentPage ne pi.maxPage}"> // 마지막페이지가 아닐때
<li class="page-item">
<a class="page-link" href="${url}${pi.currentPage+1}${searUrl}">Next</a></li>
</c:if>
</ul>
</div>
<form id="searchForm" method="get" action="${boardCode}" align="center">
<div class="select">
<select class="custom-select" name="condition">
// option 체크가 'writer'라면 페이지 변경시에도 검색값이 유지되게 함
<option value="writer" ${param.condition eq 'writer' ? 'selected' : '' }>작성자</option>
<option value="title" ${param.condition eq 'title' ? 'selected' : '' }>제목</option>
<option value="content" ${param.condition eq 'content' ? 'selected' : '' }>내용</option>
<option value="titleAndContent" ${param.condition eq 'titleAndContent' ? 'selected' : '' }>제목+내용</option>
</select>
</div>
<div class="text">
<input type="text" class="form-control" name="keyword" value="${param.keyword}"/>
</div>
<button type="submit" class="searchBtn btn btn-secondary">검색</button>
</form>
// Pagination.java
public class Pagination {
public static PageInfo getPageInfo(int listCount, int currentPage,
int pageLimit, int boardLimit) {
int maxPage =(int)(Math.ceil(((double)listCount/boardLimit)));
int startPage = (currentPage-1) / pageLimit * pageLimit+1;
int endPage = startPage+pageLimit-1;
if(endPage>maxPage) {
endPage=maxPage;
}
PageInfo pageinfo = new PageInfo();
pageinfo.setBoardLimit(boardLimit);
pageinfo.setCurrentPage(currentPage);
pageinfo.setEndPage(endPage);
pageinfo.setListCount(listCount);
pageinfo.setMaxPage(maxPage);
pageinfo.setPageLimit(pageLimit);
pageinfo.setStartPage(startPage);
return pageinfo;
}
}