JSP-웹페이지 구현(Paging)

임재헌·2023년 4월 18일
0

JSP

목록 보기
21/33

페이징

한페이지당 글이 5개씩 들어가도록 페이징

알고리즘 설정


-rownum 줄번호 활용
select bbsno,wname, readcnt, indent, regdt
from tb_bbs
order by grpno desc, ansnum asc;

2.
select bbsno,wname, readcnt, indent, regdt,rownum
from tb_bbs
order by grpno desc, ansnum asc;

3. 셀프조인 후,rownum
select bbsno,wname, readcnt, indent, regdt,rownum
from(
select bbsno,wname, readcnt, indent, regdt
from tb_bbs
order by grpno desc, ansnum asc);

----글 5개를 기준으로 자름

4.
---1~5
select bbsno,wname, readcnt, indent, regdt,rownum
from(
select bbsno,wname, readcnt, indent, regdt
from tb_bbs
order by grpno desc, ansnum asc)
where rownum<=5;


5.--6~10행 출력하기
-- 선택된 레코드가 없음
select bbsno,wname, readcnt, indent, regdt,rownum
from(
select bbsno,wname, readcnt, indent, regdt
from tb_bbs
order by grpno desc, ansnum asc)
where rownum>=6 and rownum<=10;

6.--6~10행 출력하기
--한번 더 검색해서 join
select *
from(
	select bbsno,wname, readcnt, indent, regdt,rownum as r
	from(
		select bbsno,wname, readcnt, indent, regdt
		from tb_bbs
		order by grpno desc, ansnum asc))
where r>=6 and r<=10;

7.
--페이징 + 검색
파스타가 있는 행을 검색해서 2페이지 조회하시오
select *
from(
	select bbsno,wname, readcnt, indent, regdt,rownum as r
	from(
		select bbsno,wname, readcnt, indent, regdt
		from tb_bbs
		where subject like '%파스타%'
		order by grpno desc, ansnum asc))
where r>=6 and r<=10;

ssi.jsp 공통코드 추가

int nowPage=1;
if(request.getParameter("nowPage")!=null){
	nowPage=Integer.parseInt(request.getParameter("nowPage"));
}

%>

bbsList.jsp 수정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp" %>

<!-- 본문 시작 -->
<h3>글목록</h3>
<p><a href="bbsForm.jsp">글쓰러 가기</a></p>

<table class="table table-hover" border="1">
<thead>
<tr class="info" >
<th>제목</th>
<th>조회수</th>
<th>작성자</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<%
//한페이지당 출력할 행의 갯수
//페이지 요청이 없는 경우 1페이지가 무조건 출력
int recordPerPage=5;


ArrayList<BbsDTO> list = dao.list3(col,word,nowPage,recordPerPage);
if(list==null){
	out.println(" <tr>");
	out.println(" <td colspan='5'>" );
	out.println(" <strong> 작성 글없음 <strong>" );
	out.println(" </td>" );
	out.println(" <tr>");
}else{
	//오늘 날짜를 문자열로 2023-04-14
	String today=Utility.getDate();
	
	
	for(int i=0;i<list.size();i++){
	dto=list.get(i);
%>
<tr>
<td style="text-align:left">
<%
//답변 이미지 출력
for(int n=1;n<=dto.getIndent();n++){
	out.println("<img src='../images/reply.gif'>");
}

%>


<a href="bbsRead.jsp?bbsno=<%=dto.getBbsno()%>&col=<%=col%>&word=<%=word%>&nowPage=<%=nowPage%>"><%=dto.getSubject()%></a>

<%
	//오늘 작성한 글 제목 뒤에 new 이미지 출력
	//작성일(regdt)에서 년월일	자르기
	String regdt=dto.getRegdt().substring(0,10);
	if(regdt.equals(today)){
		out.println("<img src='../images/new.gif'>");
	}
	
	//조회수 10이상 hot 이미지 출력
	if(dto.getReadcnt()>=10){
		out.println("<img src='../images/hot.gif'>");
	}
%>


</td>
<td><%=dto.getReadcnt() %></td>
<td><%=dto.getWname() %></td>
<td><%=dto.getRegdt().substring(0,10) %>
</td>
</tr>

<%
	}
	
	int totalRecord=dao.count2(col,word);
	out.println("<tr>");
	out.println("<td colspan='4' style='text-align:center;'>");
	out.println("	글갯수:<strong>" +totalRecord +"</strong>");
	out.println("</td>");
	out.println("</tr>");
	
	//페이지 리스트
	out.println("<tr>");
	out.println("<td colspan='4' style='text-align:center; height:50px'>");
	
	//String paging=new Paging().paging1(totalRecord, nowPage, recordPerPage, col, word, "bbsList.jsp") ;
	
	String paging=new Paging().paging2(totalRecord, nowPage, recordPerPage, col, word, "bbsList.jsp") ;
	
	out.println(paging);
	
	out.println("</td>");
	out.println("</tr>");
	
	
	
	
	
	
	
	
	
	
	
%>	
	<tr>
	<td colspan="4" style='text-align: center; height: 50px'>
	<form action="bbsList.jsp" onsubmit="return searchCheck()">
		<select name="col">
		<option value="subject_content">제목+내용 
		<option value="subject">제목
		<option value="content">내용
		<option value="wname">작성자
		</select>
		<input type="text" name="word" id="word">
		<input type="submit" value="검색">
	</form>	
	</td>
	</tr>
	
	
<%	
}
%>
</tbody>
</table>
<!-- 본문 끝 -->

<%@ include file="../footer.jsp" %>

BbsDAO.java

위에서 정의한 sql문을 바탕으로 작성

public ArrayList<BbsDTO> list3(String col, String word,int nowPage, int recordPerPage) {
		ArrayList<BbsDTO> list= null;
		//페이지당 출력할 행의 갯수(10개를 기준)
        //1 페이지 : WHERE r>=1  AND r<=10;
        //2 페이지 : WHERE r>=11 AND r<=20;
        //3 페이지 : WHERE r>=21 AND r<=30;
		int startRow = ((nowPage-1) * recordPerPage) + 1 ;
        int endRow   = nowPage * recordPerPage;
		
		try {
			con=dbopen.getConnection();
			sql=new StringBuilder();
				
			word=word.trim();

			if(word.length()==0) {//검색어가 존재하지 않는 경우
				sql.append(" select * ");
				sql.append(" from( ");	
				sql.append("       select bbsno, wname, readcnt,subject, indent, regdt,rownum as r ");	
				sql.append("       from( ");	
				sql.append("             select bbsno,wname, readcnt,subject, indent, regdt ");	
				sql.append("             from tb_bbs ");	
				sql.append("             order by grpno desc, ansnum asc)) ");	
				sql.append(" where r>=" + startRow +"and r<=" + endRow );	
				
			} else { //검색어가 존재하는 경우 
				sql.append(" select * ");
				sql.append(" from( ");	
				sql.append(" select bbsno,wname, readcnt,indent,subject,regdt,rownum as r ");	
				sql.append(" from( ");	
				sql.append(" select bbsno,wname, readcnt,subject,indent, regdt ");	
				sql.append(" from tb_bbs ");	
			
				String search="";
				if(col.equals("subject_content")) {
					search+= " where subject like '%" +word+"%' ";
					search+= " or content like '%" +word+"%' ";
				}else if(col.equals("subject")) {
					search+= " where subject like '%" +word+"%' ";
				}else if(col.equals("content")) {
					search+= " where content like '%" +word+"%' ";
				}else if(col.equals("wname")) {
					search+= " where wname like '%" +word+"%' ";
				}
				
				sql.append(search);
			
				sql.append(" order by grpno desc, ansnum asc)) ");	
				sql.append(" where r>=" + startRow +"and r<=" + endRow );	
			}//if end
				
				pstmt=con.prepareStatement(sql.toString());
				rs=pstmt.executeQuery();
				
				if(rs.next()){
					list=new ArrayList<>();
					do {	//커서가 가리키는 한줄씩 저장
						BbsDTO dto=new BbsDTO();
						dto.setBbsno(rs.getInt("bbsno"));;
						dto.setWname(rs.getString("wname"));
						dto.setSubject(rs.getString("subject"));
						dto.setReadcnt(rs.getInt("readcnt"));
						dto.setRegdt(rs.getString("regdt"));
						dto.setIndent(rs.getInt("indent"));
						list.add(dto);//list에 저장
						
					}while(rs.next());
				}//if end
				
			
		}catch (Exception e) {
			System.out.println("목록 가져오기 실패"+e);
		}finally {
			DBClose.close(con,pstmt,rs);
		}
		return list;
	}

Paging.java

페이징 관련 함수를 정의해서 사용한다.

package net.utility;

public class Paging {  
  /**
   * 숫자 형태의 페이징, 1 페이지부터 시작
   * 현재 페이지: 11 / 22   [이전] 11 12 13 14 15 16 17 18 19 20 [다음]
   * 
   * @param totalRecord 전체 레코드수
   * @param nowPage     현재 페이지
   * @param recordPerPage 페이지당 레코드 수 
   * @return
   */
  public String paging1(int totalRecord, int nowPage, int recordPerPage, String col, String word, String filenm){
    int pagePerBlock = 10; // 블럭당 페이지 수 
    int totalPage = (int)(Math.ceil((double)totalRecord/recordPerPage)); // 전체 페이지 
    int totalGrp = (int)(Math.ceil((double)totalPage/pagePerBlock));// 전체 그룹
    int nowGrp = (int)(Math.ceil((double)nowPage/pagePerBlock));    // 현재 그룹
    int startPage = ((nowGrp - 1) * pagePerBlock) + 1; // 특정 그룹의 페이지 목록 시작 
    int endPage = (nowGrp * pagePerBlock);             // 특정 그룹의 페이지 목록 종료  
    
    StringBuffer str = new StringBuffer();
    
    str.append("<style>");
    str.append("  #paging {text-align: center; margin-top: 5px; font-size: 1em;}");
    str.append("  #paging A:link {text-decoration:none; color:black; font-size: 1em;}");
    str.append("  #paging A:hover{text-decoration:underline; background-color: #ffffff; color:black; font-size: 1em;}");
    str.append("  #paging A:visited {text-decoration:none;color:black; font-size: 1em;}");
    str.append("</style>");
    str.append("<DIV id='paging'>");
    //str.append("현재 페이지: " + nowPage + " / " + totalPage + "&nbsp;&nbsp;");

    int _nowPage = (nowGrp-1) * pagePerBlock; // 10개 이전 페이지로 이동
    if (nowGrp >= 2){
      str.append("[<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'>이전</A>]");
    }//if end

    for(int i=startPage; i<=endPage; i++){
      if (i > totalPage){
        break;
      }//if end
 
      if (nowPage == i){ // 현재 페이지이면 강조 효과
        str.append("<span style='font-size: 1.2em; font-weight: bold;'>"+i+"</span>&nbsp;");  
      }else{
        str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+i+"'>"+i+"</A>&nbsp;");
      }//if end      
    }//for end
    
    _nowPage = (nowGrp * pagePerBlock)+1; // 10개 다음 페이지로 이동
    if (nowGrp < totalGrp){
      str.append("[<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'>다음</A>]");
    }//if end
    str.append("</DIV>");
    
    return str.toString();
  }
  
  /**
   * SPAN태그를 이용한 박스 모델의 지원, 1 페이지부터 시작
   * 현재 페이지: 11 / 22   [이전] 11 12 13 14 15 16 17 18 19 20 [다음]
   * 
   * @param totalRecord 전체 레코드수
   * @param nowPage     현재 페이지
   * @param recordPerPage 페이지당 레코드 수 
   * @return
   */
  public String paging2(int totalRecord, int nowPage, int recordPerPage, String col, String word, String filenm){
    int pagePerBlock = 10; // 블럭당 페이지 수
    int totalPage = (int)(Math.ceil((double)totalRecord/recordPerPage)); // 전체 페이지 
    int totalGrp = (int)(Math.ceil((double)totalPage/pagePerBlock));// 전체 그룹
    int nowGrp = (int)(Math.ceil((double)nowPage/pagePerBlock));    // 현재 그룹
    int startPage = ((nowGrp - 1) * pagePerBlock) + 1; // 특정 그룹의 페이지 목록 시작 
    int endPage = (nowGrp * pagePerBlock);             // 특정 그룹의 페이지 목록 종료  
    
    StringBuffer str = new StringBuffer();
    
    str.append("<style>");
    str.append("  #paging {text-align: center; margin-top: 5px; font-size: 1em;}");
    str.append("  #paging A:link {text-decoration:none; color:black; font-size: 1em;}");
    str.append("  #paging A:hover{text-decoration:none; background-color: #CCCCCC; color:black; font-size: 1em;}");
    str.append("  #paging A:visited {text-decoration:none;color:black; font-size: 1em;}");
    str.append("  .span_box_1{");
    str.append("    font-size: 1em;");
    str.append("    border: 1px;");
    str.append("    border-style: solid;");
    str.append("    border-color: #cccccc;");
    str.append("    padding:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("    margin:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("  }");
    str.append("  .span_box_2{");
    str.append("    background-color: #CCCCCC;");
    str.append("    font-size: 1em;");
    str.append("    border: 1px;");
    str.append("    border-style: solid;");
    str.append("    border-color: #cccccc;");
    str.append("    padding:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("    margin:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("  }");
    str.append("</style>");
    str.append("<DIV id='paging'>");
    //str.append("현재 페이지: " + nowPage + " / " + totalPage + "&nbsp;&nbsp;");

    int _nowPage = (nowGrp-1) * pagePerBlock; // 10개 이전 페이지로 이동
    if (nowGrp >= 2){
      str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'><span class='span_box_1'>이전</span></A>&nbsp;");
    }

    for(int i=startPage; i<=endPage; i++){
      if (i > totalPage){
        break;
      }
 
      if (nowPage == i){
        str.append("<span class='span_box_2'>&nbsp;"+i+"&nbsp;</span>&nbsp;");
      }else{
        str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+i+"'><span class='span_box_1'>&nbsp;"+i+"&nbsp;</span></A>&nbsp;");  
        		// 검색어+현재 페이지 가져감 filenm ->bbsList.jsp를 String filenm에 넘김
        
      }
    }
    
    _nowPage = (nowGrp * pagePerBlock)+1; // 10개 다음 페이지로 이동
    if (nowGrp < totalGrp){
      str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'><span class='span_box_1'>다음</span></A>&nbsp;");
    }
    str.append("</DIV>");
    
    return str.toString();
  }
  
  /**
   * SPAN태그를 이용한 박스 모델의 지원, 1 페이지부터 시작
   * 현재 페이지: 11 / 22   [이전] 11 12 13 14 15 16 17 18 19 20 [다음]
   * 
   * @param totalRecord 전체 레코드수
   * @param nowPage     현재 페이지
   * @param recordPerPage 페이지당 레코드 수 
   * @return
   */
  public String paging3(int totalRecord, int nowPage, int recordPerPage, String col, String word, String filenm){
    int pagePerBlock = 10; // 블럭당 페이지 수
    int totalPage = (int)(Math.ceil((double)totalRecord/recordPerPage)); // 전체 페이지 
    int totalGrp = (int)(Math.ceil((double)totalPage/pagePerBlock));// 전체 그룹
    int nowGrp = (int)(Math.ceil((double)nowPage/pagePerBlock));    // 현재 그룹
    int startPage = ((nowGrp - 1) * pagePerBlock) + 1; // 특정 그룹의 페이지 목록 시작 
    int endPage = (nowGrp * pagePerBlock);             // 특정 그룹의 페이지 목록 종료  
    
    StringBuffer str = new StringBuffer();
    
    str.append("<style>");
    str.append("  #paging {text-align: center; margin-top: 5px; font-size: 1em;}");
    str.append("  #paging A:link {text-decoration:none; color:black; font-size: 1em;}");
    str.append("  #paging A:hover{text-decoration:none; background-color: #CCCCCC; color:black; font-size: 1em;}");
    str.append("  #paging A:visited {text-decoration:none;color:black; font-size: 1em;}");
    str.append("  .span_box_1{");
    str.append("    font-size: 1em;");
    str.append("    border: 1px;");
    str.append("    border-style: solid;");
    str.append("    border-color: #cccccc;");
    str.append("    padding:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("    margin:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("  }");
    str.append("  .span_box_2{");
    str.append("    background-color: #668db4;");
    str.append("    color: #FFFFFF;");
    str.append("    font-size: 1em;");
    str.append("    border: 1px;");
    str.append("    border-style: solid;");
    str.append("    border-color: #cccccc;");
    str.append("    padding:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("    margin:0px 0px 0px 0px; /*위, 오른쪽, 아래, 왼쪽*/");
    str.append("  }");
    str.append("</style>");
    str.append("<DIV id='paging'>");
    //str.append("현재 페이지: " + nowPage + " / " + totalPage + "&nbsp;&nbsp;");

    int _nowPage = (nowGrp-1) * pagePerBlock; // 10개 이전 페이지로 이동
    if (nowGrp >= 2){
      str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'><span class='span_box_1'>이전</span></A>&nbsp;");
    }

    for(int i=startPage; i<=endPage; i++){
      if (i > totalPage){
        break;
      }
 
      if (nowPage == i){
        str.append("<span class='span_box_2'>&nbsp;"+i+"&nbsp;</span>&nbsp;");
      }else{
        str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+i+"'><span class='span_box_1'>&nbsp;"+i+"&nbsp;</span></A>&nbsp;");  
      }
    }
    
    _nowPage = (nowGrp * pagePerBlock)+1; // 10개 다음 페이지로 이동
    if (nowGrp < totalGrp){
      str.append("<A href='./"+filenm+"?col="+col+"&word="+word+"&nowPage="+_nowPage+"'><span class='span_box_1'>다음</span></A>&nbsp;");
    }
    str.append("</DIV>");
    
    return str.toString();
  }
}//class end

0개의 댓글