2014년 1월 3일 금요일

24. Spring Framework3.2/MyBatis게시판(페이징처리) - 유경석 [게시판 페이지나누기]

24. Spring Framework3.2/MyBatis게시판(페이징처리) - 유경석 [게시판 페이지나누기]


BoardMultiController.java

package board.controller;

import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.model.RowNumDTO;
import onj.board.service.BoardService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

@Controller
public class BoardMultiController{
@Autowired
private BoardService boardService;
 
// 페이지 사이즈, 페이지 그룹
private final int PAGESIZE  = 3;
private final int PAGEGROUP = 1;  
 
// 게시판 리스트 보기, 페이징 기능은 구현 O
@RequestMapping("/list")
public ModelAndView list(String pageNumber)throws Exception{
ModelAndView mav = new ModelAndView();
List<BoardDTO> list = null;
// 현재 클릭 페이지
int pageNum = 1;
if(pageNumber != null)pageNum = Integer.parseInt(pageNumber);
// 게시글 전체수 변수 초기화 
int totalCount = boardService.boardCount();
// 페이지 갯수
int totalPageCount = totalCount / PAGESIZE;
// 0으로 나눠 떨어지지 않을경우 페이지 갯수를 +1한다.
if(totalCount % PAGESIZE != 0){totalPageCount++;}
// startPage or endPage
int startPage = (pageNum - 1) / PAGEGROUP * PAGEGROUP +1;
int endPage   = startPage + (PAGEGROUP-1);
if(endPage > totalPageCount){endPage = totalPageCount;} 
// 마지막, 처음 rowNumber 선언 및 초기화
int endRow   = PAGESIZE*pageNum; 
int startRow = endRow - PAGESIZE+1;
 
RowNumDTO rowNumDTO = new RowNumDTO();
rowNumDTO.setStartRow(startRow);
rowNumDTO.setEndRow(endRow);
list = boardService.boardList(rowNumDTO);
mav.addObject("boardCount", list.size());
mav.addObject("totalPageCount", totalPageCount);
mav.addObject("startPage", startPage);
mav.addObject("endPage", endPage);
mav.addObject("list", list);
mav.setViewName("list");
return mav;
}
    //게시글 읽기
@RequestMapping("/read")
    public ModelAndView read(@RequestParam("seq")String seq) throws Exception { 
ModelAndView mav = new ModelAndView("read","read",boardService.readContent(seq));
//해당 글의 커멘트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
             
    }
// 커멘트 쓰기
@RequestMapping("/comment")
public ModelAndView comment(@RequestParam("seq")String seq,
@RequestParam("name")String name, 
@RequestParam("comm")String comm){
 
CommentDTO commentDTO = new CommentDTO();
commentDTO.setSeq(Integer.parseInt(seq));
commentDTO.setName(name);
commentDTO.setComment(comm); 
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq="+seq);
}
@RequestMapping("/writeOk")
    public ModelAndView writeOk(HttpServletRequest req, HttpServletResponse res)
            throws Exception {
return  new ModelAndView("write");
}
// 새글(게시글) DB입력
@RequestMapping("/write")
public ModelAndView write(HttpServletRequest req, HttpServletResponse res)throws Exception{
MultipartRequest multi = new MultipartRequest(req, "D:/upload",5*1024*1024,"euc-kr",new DefaultFileRenamePolicy());
 
Enumeration formNames = multi.getFileNames();  
String formName = (String)formNames.nextElement();
String fileName =  multi.getFilesystemName(formName);
String name = multi.getParameter("name");
String passwd = multi.getParameter("passwd");
String title  = multi.getParameter("title");
String content= multi.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return new ModelAndView("redirect:/list.html");
}
// 글 수정
@RequestMapping("/update") 
public ModelAndView update(@RequestParam("seq")String seq,
  @RequestParam("name")String name,
  @RequestParam("title")String title,
  @RequestParam("content")String content
  ){  
BoardDTO board = new BoardDTO(name, title, content);
board.setSeq(Integer.parseInt(seq));
boardService.updateBoard(board); 
return new ModelAndView("redirect:/read.html?seq="+seq);
}
// 게시글 삭제
@RequestMapping("/delete")
public ModelAndView delete(@RequestParam("seq")String seq,
  @RequestParam("passwd")String passwd,
  HttpServletResponse res
  )throws Exception{
BoardDTO boardDto = new BoardDTO();
boardDto.setSeq(Integer.parseInt(seq));
boardDto.setPasswd(passwd);
int result = boardService.deleteBoard(boardDto);
if(result != 1){
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1)</script>");
return null;
}else{
return new ModelAndView("redirect:/list.html"); 
}
}
// 게시물 상세보기에서 답변 클릭 시 호출되어 답변을 달 reply.jsp로 연결
@RequestMapping("/reply")
public ModelAndView reply(@RequestParam("seq")String seq){
// 답변달 게시물 내용을 reply.jsp 넘긴다.
ModelAndView mav = new ModelAndView("reply","reply",boardService.readContent(seq));
 
return mav; 
}
// 답글 저장
@RequestMapping("/replyok")
public ModelAndView replyok(
   @RequestParam("name")String name,
   @RequestParam("passwd")String passwd,
   @RequestParam("title")String title,
   @RequestParam("content")String content,
   @RequestParam("reply")String reply,
   @RequestParam("reply_step")String reply_step,
   @RequestParam("reply_level")String reply_level
   ) throws Exception{
 
BoardDTO boardDTO = new BoardDTO(name,passwd,title,content,"");

boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardService.replyBoard(boardDTO);
return new ModelAndView("redirect:/list.html");
}
}

------------------------------------------------------------------------------------------

RowNumDTO.java

package onj.board.model;

public class RowNumDTO {
// 한 페이지의 시작 or 끝 번호 
private int startRow;
private int endRow;
public int getStartRow() {
return startRow;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public int getEndRow() {
return endRow;
}
public void setEndRow(int endRow) {
this.endRow = endRow;
}
}

------------------------------------------------------------------------------------------

sqlmap-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<typeAliases>
<typeAlias type="onj.board.model.BoardDTO" alias="boardDTO"/>
<typeAlias type="onj.board.model.CommentDTO" alias="commentDTO"/>
<typeAlias type="onj.board.model.RowNumDTO" alias="RowNumDTO"/>
</typeAliases>
</configuration>

------------------------------------------------------------------------------------------

boardSql.xml

<!-- 게시판 전체 리스트 보기(페이지처리) -->
<select id="boardList" parameterType="RowNumDTO" resultMap="boardDTO">
select * from
 (select 
           seq, name, passwd, title, content, filename, regdate,                                                             readcount, reply, reply_step, reply_level, rownum r 
           from 
  (select * 
                                           from 
                                                 board
                                           order by 
                                                      reply_step asc ,reply desc      
                                           )
           )  
where  r between #{startRow} and #{endRow} 
</select>


------------------------------------------------------------------------------------------

SpringBoardDAO.java

package onj.board.dao;

import java.util.List;

import javax.annotation.Resource;

import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.model.RowNumDTO;

import org.apache.ibatis.session.SqlSession;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

@Component("BoardDAO")
public class SpringBoardDAO implements BoardDAO{

@Resource(name="sqlSession")
private SqlSession sqlSessionTemplate;

String sql ="";

public String getSql(){return sql;}
// 게시판 전체 리스트 보기
public List<BoardDTO> boardList(RowNumDTO rowNumDTO) throws DataAccessException{
List<BoardDTO> boardList = null;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
boardList = boardDao.boardList(rowNumDTO);
return boardList;
}
// 게시판 전체 수
public int boardCount()throws DataAccessException{
int count = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
count = boardDao.boardCount();
return count;
}

// 게시물 본문내용 미리보기(/preView)
public String preView(String seq) throws DataAccessException {
String preContent;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
preContent = boardDao.preView(seq);
return preContent;
}
// 게시판 상세보기, 게시글 읽기
public BoardDTO readContent(String seq) throws DataAccessException{

BoardDTO boardDto = null;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
boardDto = boardDao.readContent(seq);
// 글 조회 1증가
this.updateReadCount(new Integer(seq).toString());
return boardDto;
}
// 읽은 글의 조회수를 1증가
public int updateReadCount(String seq) throws DataAccessException{
int count = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
count = boardDao.updateReadCount(seq);
return count;
}
// 커멘트 입력
public int insertComment(CommentDTO commentDTO)throws DataAccessException{
int re = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
re = boardDao.insertComment(commentDTO);
 
return re;
}
 
// 커멘트 조회
public List<CommentDTO> commentList(String seq) throws DataAccessException{
List<CommentDTO> list = null;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
list = boardDao.commentList(seq);
return list; 
}
 
// 글쓰기
public int insertBoard(BoardDTO board) throws DataAccessException{
int re = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
if(board.getFileName() == null){
board.setFileName(""); 
}
re = boardDao.insertBoard(board);
return re;
}

// 글 수정 
public int updateBoard(BoardDTO board) throws DataAccessException {
int re = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
re = boardDao.updateBoard(board);
return re;
}

// 게시글 삭제
public int deleteBoard(BoardDTO boardDto)
throws DataAccessException {
int re = 0;
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
re = boardDao.deleteBoard(boardDto);
return re;
}

// 답글 step plus
public void replyBoardStep(BoardDTO boardDto) throws DataAccessException {
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
boardDao.replyBoardStep(boardDto);
}

// 달급달기
public int replyBoard(BoardDTO boardDTO) throws DataAccessException {
int re = 0;
this.replyBoardStep(boardDTO);
BoardDAO boardDao = sqlSessionTemplate.getMapper(BoardDAO.class);
re = boardDao.replyBoard(boardDTO);
return re; 
}
}

------------------------------------------------------------------------------------------

list.jsp

<%@ page contentType="text/html; charset=euc-kr" language="java" import="java.sql.*" errorPage="" %>
<%@ page import = "javax.rmi.* , javax.naming.* , java.util.* , onj.board.model.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<style type="text/css">
#layer1{
position: absolute;
padding : 5px; 
filter  : alpha(opacity=50);
width   : 250px;
height  : 150px;
background-color: white;
border: 2px #000000 dotted;
visibility: hidden;
  }
</style>
 
<script type="text/javascript" src="/Spring_board/js/createXMLHttpRequest.js"></script>

<script type="text/javascript">
var xmlHttp;
var xmlDoc;
var message;
function contentprev(seq) {
// 미리보기 서블릿 호출
var url = "preView?seq="+seq;
xmlHttp = createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange; 
xmlHttp.open("get",url,true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
xmlDoc = xmlHttp.responseText; 
document.getElementById("layer1").innerHTML = xmlDoc; 
}
}
}  
function showlayer(id){
if(document.all) 
document.all[id].style.visibility="visible";
else if(document.layers)
document.layers[id].style.visibility="visible";
}
function hidelayer(id){
if(document.all)
document.all[id].style.visibility="hidden";
else if(document.layers)
document.layers[id].style.visibility="hidden";
}
function movetip(){
        layer1.style.pixelTop=event.y+document.body.scrollTop+10;
        layer1.style.pixelLeft=event.x+document.body.scrollLeft+10;
}  
document.onmousemove=movetip;    
</script> 

<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<title>오엔제이 프로그래밍 실무학원</title>
</head>
<body>
<div id="layer1">
  게시물 본문 미리 보기
</div> 
<div style="width:500px;">
<div>
<H3>오엔제이 프로그래밍 실무교육센터 게시판</H3>
<h5>총 ${boardCount}건</h5>  

<table width="600" border="0" align="left">
  <tr align="left"> 
    <td width="10%" align="center">번호</td>
    <td width="40%" align="center">제목</td> 
    <td width="20%" align="center">이름</td>
    <td width="20%" align="center">날짜</td>
    <td width="10%" align="center">조회</td>
  </tr>

             <c:forEach var="board" items="${list}">      
  <tr>
    <td align="center">
                    <c:if test="${board.reply_step == 0}">
                                 ${board.seq}
                    </c:if>                  
    </td>
    <td>      <!-- 게시물은 덧글에 따른 번호와 덧글 존재 유무로 정렬됨 -->
                    <c:choose>
                                    
                           <c:when test="${board.reply_step == 0}">
                                        <a href="read.html?seq=${board.seq}"  onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>                    
                           </c:when>
                           
                           <c:when test="${board.reply_step != 0}"><!-- 게시글이 덧글일 경우 -->
                           
                                 <c:forEach var="i" begin="1" end="${board.reply_level}" step="1"><!-- 레벨의 수만큼 글을 뒤로 민다 -->
                                ..
                                 </c:forEach>
                                        <a href="read.html?seq=${board.seq}" onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>
                                        <!-- 마우스를 올리면 게시물 번호에 따른 showlayer(게시물 미리보기 창)가 실행됨 -->
                           </c:when>
                           
                    </c:choose>
   </td>
    <td align="center">${board.name}</td>
    <td align="center">${board.regdate}</td>
    <td align="center">${board.readCount}</td> 
  </tr> 
             </c:forEach> 
 
</table>
 
<table width="600">
<tr>
<td colspan="5" align="center"> 
<c:if test="${startPage>1}"> 
<span>
<a href="/Spring_board/list.html?pageNumber=${startPage-1}">이전</a>
</span>
</c:if>
<c:forEach var="i" begin="${startPage}" end="${endPage}">
<c:choose>
<c:when test="${pageNumber == i }">
<span>
<a href="/Spring_board/list.html?pageNumber=${i}" style="text-decoration: none; color: blue; font-weight: bold;">${i}</a>&nbsp;
</span>
</c:when>
<c:otherwise>
<span>
<a href="/Spring_board/list.html?pageNumber=${i}" style="text-decoration: none; color: gray;">${i}</a>&nbsp;
</span> 
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${endPage < totalPageCount}">
<span>
<a href="/Spring_board/list.html?pageNumber=${endPage+1}">다음</a>
</span>
</c:if>
</td>
</tr>
</table>
<table width="600">
  <tr>
    <td colspan="5" align="right"><input type="submit" value="쓰기" onclick="location.href='/Spring_board/writeOk.html'"></td>  
  </tr>
</table>

</div>
</div>
</body>
</html>

댓글 없음:

댓글 쓰기