2022-01-12 model2 페이징, 댓글 수 표시 / 첨부파일 업로드
페이징
2. Paging 클래스에 paging() 메소드 생성
private void paging() {
//각 멤버 변수 값 세팅
double temp = Math.ceil(page/(double)displayPage);
endPage = (int)(temp * displayPage);
beginPage = endPage - displayPage + 1 ;
int totalPage = (int)Math.ceil(totalCount/(displayRow));
//총 게시물 수를 한 화면에 표시할 게시물 수로 나눠서 총 페이지 갯수를 계산
if(totalPage < endPage) {//총 페이지가 화면에 표시할 끝페이지보다 작다면
endPage = totalPage;
next = false;
} else {
next = true;
}
prev = (beginPage==1)? false:true;
startNum = (page-1)*displayRow+1;
//현재 화면의 시작 게시물 번호 : 1페이지-1, 2페이지-11, 3페이지-21 ...
endNum = page*displayRow;
}
3. MainAction에 Paging객체 생성 + request.setAttribute("paging", paging); + 페이지 값 세팅
4. 전체 페이지 갯수를 알아내기 위해서 getAllCount() 메서드를 BoardDao에 생성
-> select count(*) ~~
5. MainAction에 글을 불러오는 ArrayList가 전체 글을 다 보여주는 것이 아니라 해당 페이지의 글만 표시해야 하므로 paging 처리 아래로 옮겨주고 selectBoard()메서드를 paging을 전달인수로 받는 selectBoard(paging)로 수정한다!!
-> 앞으로 무조건 계속 페이징을 통해 표시할 것이므로 오버라이드가 아니라 아예 수정해버림
6. 글 번호는 삭제나 오류 때문에 연속되지 않으므로 쿼리 사용시 rownum을 사용하여야 한다.
select rownum, sub.* from (select * from board order by num desc) sub;
-- rownum과 *은 함께 사용할 수 없으므로 서브쿼리로 처리한다.
select * from
(select rownum as rn, sub.* from (select * from board order by num desc) sub)
where rn>=11 and rn<20;
--원하는 rownum 범위만 골라냄 -> 게시물 갯수가 많아지면 명령의 실행 속도가 느려짐
select * from
(select * from
(select rownum as rn, sub.* from (select * from board order by num desc) sub)
where rn>=11) where rn<=20;
--범위를 좁혀서 검색 속도를 향상 시킴
7. 위 sql에 맞추어 selectBoard메소드 수정
public ArrayList<BoardDto> selectBoard(Paging paging){
ArrayList<BoardDto> list = new ArrayList<>();
//String sql = "select * from board order by num desc";
String sql = "select * from "
+"(select * from "
+ "(select rownum as rn, sub.* "
+ "from (select * from board order by num desc) sub) "
+ "where rn>=?) where rn<=?";
con = Dbman.getConnection();
try {
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, paging.getStartNum());
pstmt.setInt(2, paging.getEndNum());
rs = pstmt.executeQuery();
while(rs.next()) {
BoardDto bdto = new BoardDto();
bdto.setNum(rs.getInt("num"));
bdto.setUserid(rs.getString("userid"));
bdto.setPass(rs.getString("pass"));
bdto.setEmail(rs.getString("email"));
bdto.setTitle(rs.getString("title"));
bdto.setReadcount(rs.getInt("readcount"));
bdto.setWritedate(rs.getTimestamp("writedate"));
list.add(bdto);
}
} catch (SQLException e) { e.printStackTrace();
} finally { Dbman.close(con, pstmt, rs); }
return list;
}
8. main.jsp에 페이지 태그 추가
-> 만약 현재 보고 있는 페이지와 클릭한 페이지가 다르다면 클릭한 페이지로 이동
-> prev, next 표시
<div id="paging" align="center" style="font-size:110%; font-wight:bold;">
<!-- 페이지가 클릭될때마다 이동할 링크 기본 경로를 변수에 저장 -->
<c:url var="action" value="board.do?command=main"/>
<c:if test="${paging.prev}">
<a href="${action}&page=${paging.beginPage-1}">◀</a>
<!-- 링크되는 주소 : board.do?command=main&page=??-->
</c:if>
<!-- 실제 페이지들이 표시되는 곳 -->
<c:forEach begin="${paging.beginPage}" end="${paging.endPage}" var="index">
<c:choose>
<c:when test="${paging.page==index}">
<span style="color:red">${index} </span>
</c:when>
<c:otherwise>
<a href="${action}&page=${index}">${index}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${paging.next}">
<a href="${action}&page=${paging.endPage+1}">▶</a>
</c:if>
</div>
댓글 수 표시
페이지에 보이는 게시글의 댓글 수만 불러올 것
1.board 테이블에 댓글 수를 저장할 replycnt 컬럼 생성
alter table board add replycnt number(3) default 0;
2. BoardDto에 replycnt 변수 선언하고 getter, setter 설정
3. 현제 replycnt 값은 전부 null이므로 작성된 댓글 수를 불러와야함
-> 게시물 번호를 전달인수로 댓글 수를 얻어오는 메소드 생성
public int getReplycnt(int num) {
int cnt = 0;
String sql = "select count(*) as cnt from reply where boardnum=?";
con=Dbman.getConnection();
try {
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()) cnt = rs.getInt("cnt");
} catch (SQLException e) {e.printStackTrace();
} finally {Dbman.close(con, pstmt, rs);}
return cnt;
}
4. main.jsp의 제목을 표시하는 태그 옆에 [댓글수] 추가
-> 댓글 수가 0이면 표시하지 않음
<td align="left">
<a href="board.do?command=boardView&num=${board.num}">
${board.title}
<c:if test="${board.replycnt>0}">
<span style="color:red; font-weight:bold;">
[${board.replycnt}]
</span>
</c:if>
</a>
</td>
댓글 수 생성 완료
게시판은 마무리 -> 전체 코드는 보호글
첨부 파일 업로드 하기
1. 새로운 다이내믹웹프로젝트 생성 + project Facet, WEB-INF/lib에 jar파일 3개 넣기
2. https://www.servlets.com/ 에 접속
압축을 풀고 lib 파일 안에 있는 cos.jar를 WEB-INF/lib에 추가
3. 새로운 jsp파일 열기
※파일 업로드 기능이 포함된 form은 반드시 enctype="multipart/form-data" 옵션을 추가 해야 함
method는 반드시 post일 것
<body>
<form action="upload.do" method="post" enctype="multipart/form-data">
글쓴이 : <input type="text" name="name"><br>
제 목 : <input type="text" name="title"><br>
파일 지정하기 : <input type="file" name="uploadFile"><br>
<input type="submit" value="전송">
</form>
<!-- <img src="upload/jquery.jpg" width="300"/> -->
</body>
4. upload.do(UploadServlet) 만들기
doPost는 doGet(request, response); 이 상태로 내버려두고 doGet 수정
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//1) 파일이 업로드 될 타겟 폴더 이름 저장
String savePath = "upload";
//2) 업로드될 파일의 용량을 제한 지정
int uploadFileSizeLimit=5*1024*1024; //5Mb
//3) 인코딩 방식 저장
String encType="UTF-8";
//4) 업로드 될 서버의 실제 저장 장소
ServletContext context = getServletContext();
String uploadFilePath = context.getRealPath(savePath);
//MultipartRequest 객체가 생성되는 순간 업로드 되는 파일은 해당 경로에 업로드 완료됨
MultipartRequest multi = new MultipartRequest(request, uploadFilePath,
uploadFileSizeLimit, encType, new DefaultFileRenamePolicy());
System.out.println("request로 처리 : " + request.getParameter("name"));
System.out.println("multi로 처리 : " + multi.getParameter("name"));
//jsp 파일의 form에서 전달된 파일의 이름 및 그 외 항목들을 파라미터로 추출
String name = multi.getParameter("name");
String title = multi.getParameter("title");
String fileName = multi.getFilesystemName("uploadFile");
request.setAttribute("name", name);
request.setAttribute("title", title);
request.setAttribute("fileName", fileName);
RequestDispatcher dp = request.getRequestDispatcher("01_result.jsp");
dp.forward(request,response);
}
* 1024byte=12Kbyte, 1024Kbyte=1Mb
※MultipartRequest는 cos.jar 안에 있는 파일 업로드에 중요한 역할을 하는 클래스.
- enctype="multipart/form-data"로 보낸 데이터들은 일반 request로 전달 받을 수 없으므로 MultipartRequest에 request를 넣어 사용할 수 있도록 설정
- DefaultFileRenamePolicy : 업로드 파일과 동일한 이름이 이미 존재하면 새 이름을 부여해주는 역할
5. 결과를 표시할 jsp파일 만들기
<body>
<h3>
글쓴이 : ${name}<br>
제목 : ${title}<br>
이미지 : <img src = "upload/${fileName}" width="200"/>
</h3>
</body>
이미지 주소를 복사해 보면
http://localhost:8090/WEB11_FileUpIoad/upload/E_ugmLCWUAAsuWk1.jpg 라고 나오는데 실제 경로의 upload 폴더에 가보면 파일이 해당 파일이 없다
-> 실제로 파일이 업로드 되는 uploadFilepath를 출력해보면
워크스페이스경로\metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\WEB11_FileUpIoad\upload
경로대로 찾아가보면 여기에 파일이 저장되어 있다.
-> 같은 사진 파일들이 DefaultFileRenamePolicy에 의해 제목이 다르게 저장되었다.