일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 싱글톤
- 루프
- boxing
- 내장객체
- Short
- 싱글턴
- 언박싱
- 인텔리제이
- 무한
- 자동형변환
- Java
- 제너릭
- wrapper
- 컬렉션
- 빌드
- https://start.spring.io
- unboxing
- suvlet
- Jenkins
- 박싱
- dependency
- 콜렉션
- Scanner
- start.spring.io
- 메소드
- 클래스
- maven
- bootstrap
- 스프링
- 제네릭
- Today
- Total
Developer Gonie
[9주차] 29. {게시판} 게시글 보여주는 기능(list.jsp) 본문
list.jsp에서 구현해야할 사항
첫번째
사용자가 요청(클릭)한 페이지 번호를 넘겨받아 이에 해당하는 게시글들을 pageSize 개수만큼 보여준다.
두번째
하단에는 다른 페이지로 넘어갈 수 있도록 페이지 번호를 보여준다.
첫번째 사항 구현하기
사용자가 페이지 번호를 클릭하면 페이지 번호를 넘겨받아 해당 페이지를 보여주면 되는데,
맨 처음에는 사용자가 페이지 번호를 클릭해서 list.jsp를 접근하는게 아니기 때문에
pageNum 값을 열어봐서 null 이면 1페이지를 보여줘야 하는구나를 알도록 해줘야 한다.
그리고 한 줄로 표현할 수 있는 부분을 굳이 두 줄로 나눠 작성한 이유는
pageNum이 null인 경우 Integer.parseInt() 연산을 시도하려고 하면 에러가 나기 때문에 이렇게 구현한 것임.
String pageNum = request.getParameter("pageNum");
if(pageNum == null){
pageNum = "1"; // 맨 처음엔 첫번째 페이지가보여지므로
}
int currentPage = Integer.parseInt(pageNum);
그 다음 한 페이지에 최대 몇개의 글을 보여줄지에 대한 값을 가지는 변수를 만들어야 한다.
int pageSize = 10;
그 다음 수 많은 글들 중 현재 페이지에서는 몇번부터 몇번까지의 글을 보여줘야하는지를 구해놓는 부분이 있어야한다.
그래야 DB에서 해당 레코드들을 가져와 띄워줄 수 있지 않겠는가?
startRow, endRow는 테이블에서 num column의 값이 아니라
최신순, 가족순, 답답글 순으로 정렬하고 rank column의 값에 조건을 걸기 위한 값이라는 것을 알아야 함.
currentPage가 1이고, pageSize가 10 이라는 가정하에 startRow, endRow 는 각각 1, 10의 값을 가짐
currentPage가 2이고, pageSize가 10 이라는 가정하에 startRow, endRow 는 각각 11, 20의 값을 가짐
int startRow = (currentPage-1) * pageSize + 1;
int endRow = currentPage * pageSize;
그다음 DAO객체를 생성해서 전체 레코드의 개수를 가져와야 하는데 그 이유는 레코드가 존재하지 않을시 게시물이 존재하지 않는다는 화면을 보여주고, 0개가 아닐시 위에서 구한 startRow, endRow 값을 가지고 DB에서 이 사이의 rank 값을 가지는 것들만 select 쿼리문으로 요청하여 가져와 테이블 형태로 보여주기 위함임.
//DAO 객체 생성
BoardDao dao = BoardDao.getInstance();
//DAO 객체를 이용해 레코드의 모든 개수를 가져옴
int countAll = dao.getArticleCount(); // 레코드의 전체 개수를 가져옴, 전체 갯수를 알아야 필요한 페이지 번호를 알 수 있음
//DAO 객체를 이용해 현재 페이지에 보여줄 레코드만 가져옴
ArrayList<BoardBean> list = null;
if(countAll > 0){
list = dao.getArticles(startRow, endRow);
}
가져온 레코드들은 num 값을 가지고 있는데 이것은 DB에 삽입된 순서 값이라서 이를 그대로 보여주면 산만해 보인다.
따라서, 원래 각 row가 가지고 있는 num 값은 사용자에게 보여주지 않고, 대신 아래의 변수를 이용하여 num 값과 무관하게 제일 큰 값부터 하나씩 줄여나간 수를 앞에 보여주기 위한 변수를 둔다.
//맨 앞의 열에 오는 숫자를 1씩 줄여주며 보여주기 위한 숫자 변수
int number = countAll - (currentPage - 1) * pageSize;
이제는 가져온 데이터를 테이블 형태로 출력해주면 되는데,
먼저 열 이름을 출력해주고 만약 존재하는 게시글이 없다면 게시글이 존재하지 않는다고 보여지도록 함
<table border="1" width="700">
<caption><b>글목록(전체 글:<%=countAll %>)</b></caption>
<tr>
<td align = "right" bgcolor="<%=value_c %>">
<a href="writeFrom.jsp">글쓰기</a>
</td>
</tr>
</table>
<table border="1" width="700">
<tr bgcolor="<%=value_c%>">
<td align="center">번호</td>
<td align="center">제목</td>
<td align="center">작성자</td>
<td align="center">작성일</td>
<td align="center">조회</td>
<td align="center">IP</td>
</tr>
<%
if (countAll == 0) {
%>
<tr>
<td align="center" colspan="6">게시글이 없습니다.</td>
</tr>
<%
}
else{
...
...
%>
</table>
게시글이 존재한다면 위의 else 부분에서 아래와 같이 테이블 형태로 출력.
다만, 답글인 경우 답글, 답답글, 답답답글 별로 각각의 앞에 공백의 크기를 다르게 해주어 계단식으로 보여지게 함.
그리고, 게시글을 보여줄 때 3가지 값을 같이 넘겨주는데
1) 특정 게시글이 눌렸을 때 어떤 게시글을 선택되었는지 식별하여 해당 게시물이 띄워지도록 num을 넘겨주며
2) 특정 게시글을 눌렀다가 목록보기를 눌렀을 때, 보던 페이지가 다시 보여질 수 있게 하기 위해 현재 pageNum을 넘겨주며
3) 마지막 페이지에서 하나 남은 특정 게시물이 삭제되었을 때, 보던 페이지 바로 전 페이지를 계산하기 위해 pageSize도 넘겨준다.
else{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 날짜에 형식을 지정하는 클래스
for (int i = 0; i < list.size(); i++) {
BoardBean bean = list.get(i);
%>
<tr>
<td align="center"><%=number-- %></td> <!-- 중구난방으로 나오는 num값 대신에 그냥 하나씩 감소하는 숫자가 보여지도록 함 -->
<td>
<% //이 레코드가 원글이 아닌 답글인 경우에만 앞에 공백 이미지, re 사진을 넣어 계단식으로 보여지도록 함
if(bean.getRe_level() > 0){
int width = bean.getRe_level()*20; // 1->20, 2->40, 3-> 60
%>
<!-- 답글인 경우 답글, 답답글, 답답답글 별로 각각 앞의 공백을 다르게줌 계단식으로 보이게 -->
<img src="./images/level.gif" width="<%=width %>" height="15">
<!-- 답글의 경우 게시글의 제목 앞에 Re사진을 띄움 -->
<img src="./images/re.gif" height="15">
<%
}//if문
%>
<!-- 글보기로 넘어갔다가 다시 글목록보기로 돌아올 때, 보던 페이지를 보여주려고 pageNum도 보냄 -->
<a href="content.jsp?num=<%=bean.getNum()%>&pageNum=<%=pageNum%>&pageSize=<%=pageSize%>"><%=bean.getSubject() %></a>
<%
if(bean.getReadcount() >= 10){
%>
<img src="images/hot.gif" height="15" />
<%
}
%>
</td>
<td align="center"><%=bean.getWriter() %></td>
<td align="center"><%=sdf.format(bean.getReg_date()) %></td>
<td align="center"><%=bean.getReadcount() %></td>
<td align="center"><%=bean.getIp() %></td>
</tr>
<%
}//for
}//else
두번째 사항 구현하기
첫번째 사항을 구현하며 만든 currentPage, pageSize, countAll 변수들을 이용하여 아래 사항을 구현
<% /* 하단에 페이지번호들을 출력하는 코드 */
if(countAll > 0){
//한 번에 보여줄 페이지의 개수
int pageBlock = 10;
// currentPage 1~10페이지에서는 startPage, endPage 는 각각 1, 10
// currentPage 11~20페이지에서는 startPage, endPage 는 각각 11, 20
int startPage = (int)((currentPage - 1)/pageBlock) * pageBlock + 1;
int endPage = startPage + pageBlock - 1;
//필요한 전체 페이지 개수(바로 아래서 필요함)
int pageCount = (int)(countAll / pageSize) + (countAll%pageSize == 0 ? 0 : 1); // ex) 245개의 레코드가 있다면 25개의 페이지가 필요
//11~20페이지가 아니라 보여줄게 끝나 16페이지 까지만 필요한 경우도 있을 것이므로
if(endPage > pageCount){
endPage = pageCount;
}
if(startPage > pageBlock){
%> <a href="list.jsp?pageNum=<%=startPage-10 %>">[이전]</a> <%
}//if
for(int i=startPage; i<=endPage; i++){
%> <a href="list.jsp?pageNum=<%=i%>">[<%=i%>]</a> <%
}//for
if(endPage < pageCount){
%> <a href="list.jsp?pageNum=<%=startPage+10 %>">[다음]</a> <%
}
}
%>
첫번째 사항 구현하며 사용한 DB관련 함수 살펴보기
전체 코드
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="board.BoardBean"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@page import="board.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="color.jsp" %> <!-- 코드 이어붙이는 include 액션태그 -->
<style>
body{
text-align: center; /* body태그는 없지만 */
}
table{
margin : auto; /* 테이블 요소 가운데 정렬 */
}
</style>
list.jsp<br>
<%
//사용자가 하단에 있는 페이지 번호(<a>요소)중 하나를 클릭하면 넘겨받는 파라미터로 몇번째 페이지를 띄울 것인지 알기
//맨 처음 접속시 이 변수에 넘어오는 값이 없을 것이므로 null이 반환되면 1페이지로 인식
String pageNum = request.getParameter("pageNum");
if(pageNum == null){
pageNum = "1"; // 맨 처음엔 첫번째 페이지가보여지므로
}
int currentPage = Integer.parseInt(pageNum);
//한 페이지에 보여질 레코드 개수
int pageSize = 10;
//currentPage에 따라 DB에서 가져올 행의 시작번호, 끝번호를 계산하는 공식(이 값은 num 컬럼의 값이 아니라 rank로 필터링 할 때 사용됨)
//currentPage=1 페이지라면 startRow의 값이랑 endRow의 값은 각각 1, 10
//currentPage=2 페이지라면 startRow의 값이랑 endRow의 값은 각각 11, 20
int startRow = (currentPage-1) * pageSize + 1;
int endRow = currentPage * pageSize;
//DAO 객체 생성
BoardDao dao = BoardDao.getInstance();
//DAO 객체를 이용해 레코드의 모든 개수를 가져옴
int countAll = dao.getArticleCount(); // 레코드의 전체 개수를 가져옴, 전체 갯수를 알아야 필요한 페이지 번호를 알 수 있음
//DAO 객체를 이용해 현재 페이지에 보여줄 레코드만 가져옴
ArrayList<BoardBean> list = null;
if(countAll > 0){
list = dao.getArticles(startRow, endRow);
}
//아래서 그냥 맨 앞의 열에 오는 숫자를 1씩 줄여주며 보여주기 위한 숫자 변수
int number = countAll - (currentPage - 1) * pageSize;
%>
<table border="1" width="700">
<caption><b>글목록(전체 글:<%=countAll %>)</b></caption>
<tr>
<td align = "right" bgcolor="<%=value_c %>">
<a href="writeFrom.jsp">글쓰기</a>
</td>
</tr>
</table>
<table border="1" width="700">
<tr bgcolor="<%=value_c%>">
<td align="center">번호</td>
<td align="center">제목</td>
<td align="center">작성자</td>
<td align="center">작성일</td>
<td align="center">조회</td>
<td align="center">IP</td>
</tr>
<%
if (countAll == 0) {
%>
<tr>
<td align="center" colspan="6">게시글이 없습니다.</td>
</tr>
<%
}
else{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 날짜에 형식을 지정하는 클래스
for (int i = 0; i < list.size(); i++) {
BoardBean bean = list.get(i);
%>
<tr>
<td align="center"><%=number-- %></td> <!-- 중구난방으로 나오는 num값 대신에 그냥 하나씩 감소하는 숫자가 보여지도록 함 -->
<td>
<% //이 레코드가 원글이 아닌 답글인 경우에만 앞에 공백 이미지, re 사진을 넣어 계단식으로 보여지도록 함
if(bean.getRe_level() > 0){
int width = bean.getRe_level()*20; // 1->20, 2->40, 3-> 60
%>
<!-- 답글인 경우 답글, 답답글, 답답답글 별로 각각 앞의 공백을 다르게줌 계단식으로 보이게 -->
<img src="./images/level.gif" width="<%=width %>" height="15">
<!-- 답글의 경우 게시글의 제목 앞에 Re사진을 띄움 -->
<img src="./images/re.gif" height="15">
<%
}//if문
%>
<!-- 글보기로 넘어갔다가 다시 글목록보기로 돌아올 때, 보던 페이지를 보여주려고 pageNum도 보냄 -->
<a href="content.jsp?num=<%=bean.getNum()%>&pageNum=<%=pageNum%>&pageSize=<%=pageSize%>"><%=bean.getSubject() %></a>
<%
if(bean.getReadcount() >= 10){
%>
<img src="images/hot.gif" height="15" />
<%
}
%>
</td>
<td align="center"><%=bean.getWriter() %></td>
<td align="center"><%=sdf.format(bean.getReg_date()) %></td>
<td align="center"><%=bean.getReadcount() %></td>
<td align="center"><%=bean.getIp() %></td>
</tr>
<%
}//for
}//else
%>
</table>
<% /* 하단에 페이지번호들을 출력하는 코드 */
if(countAll > 0){
//한 번에 보여줄 페이지의 개수
int pageBlock = 10;
// currentPage 1~10페이지에서는 startPage, endPage 는 각각 1, 10
// currentPage 11~20페이지에서는 startPage, endPage 는 각각 11, 20
int startPage = (int)((currentPage - 1)/pageBlock) * pageBlock + 1;
int endPage = startPage + pageBlock - 1;
//필요한 전체 페이지 개수(바로 아래서 필요함)
int pageCount = (int)(countAll / pageSize) + (countAll%pageSize == 0 ? 0 : 1); // ex) 245개의 레코드가 있다면 25개의 페이지가 필요
//11~20페이지가 아니라 보여줄게 끝나 16페이지 까지만 필요한 경우도 있을 것이므로
if(endPage > pageCount){
endPage = pageCount;
}
if(startPage > pageBlock){
%> <a href="list.jsp?pageNum=<%=startPage-10 %>">[이전]</a> <%
}//if
for(int i=startPage; i<=endPage; i++){
%> <a href="list.jsp?pageNum=<%=i%>">[<%=i%>]</a> <%
}//for
if(endPage < pageCount){
%> <a href="list.jsp?pageNum=<%=startPage+10 %>">[다음]</a> <%
}
}
%>
'K-DigitalTraining 강의 > 8. JSP' 카테고리의 다른 글
[9주차] 28. {게시판} 게시글이 저장되는 테이블 구조(+ 원글, 답글이 DB에 추가되는 알고리즘) (0) | 2022.07.21 |
---|---|
request.getRemoteAddr() 사용시 IP를 읽어들이는 형식 변경방법 (0) | 2022.07.21 |
[9주차] 27. 파일업로드 기능구현(내장객체 config) (0) | 2022.07.20 |
[9주차] 26. JDBC에서 커넥션풀을 적용하는 방법 (0) | 2022.07.19 |
[9주차] 25. 싱글톤 패턴(객체를 1개만 생성) 방식으로 클래스를 설계하는 방법(feat. dao) (0) | 2022.07.19 |