2013년 8월 2일 금요일

15.[Spring Framework3.2 Board Example] 스프링게시판 글 수정, 자바교육,스프링교육,Spring JDBC

Spring 게시판 구현(글 수정)

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷  
실무전문 강의)

1.     시작하기
 
-       이번에는 게시판 상세보기(글 읽기) 페이지에서 글을 수정하는 기능을 추가해 보자.
 
2.     글을 수정하기 위한 DAO쪽 클래스를 작성하자.
 
BoardDAO.java 인터페이스, SpringBoardDAO.java 클래스에 입력을 위한 updateBoard() 메소드를 추가하자.
 
 
소스 코드 빨강색 부분이 추가된 부분
 
 
[BoardDAO.java]
 
package onj.board.dao;
 
import java.util.List;
 
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
 
import org.springframework.dao.DataAccessException;
 
 
public interface BoardDAO {
       //게시물 리스트 보기
       public List<BoardDTO> boardList() throws DataAccessException;
      
       //게시물 본문 미리보기
       public String preView(String seq) throws DataAccessException;
      
       //게시물 본문 읽기
       public BoardDTO readContent(String seq) throws DataAccessException;
      
       //읽은 글의 조회수 1증가
       public int updateReadCount(String seq) throws DataAccessException;
      
       //Comment저장
       public int insertComment(CommentDTO commentDTO) throws DataAccessException ;
      
       //Comment조회
       public List<CommentDTO> commentList(String seq) throws DataAccessException;
      
       //게시글 입력
       public int insertBoard(BoardDTO board) throws DataAccessException;
      
       // 수정
       public int updateBoard(BoardDTO board) throws DataAccessException;
}
 
[SpringBoardDAO.java]
 
 
package onj.board.dao;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
 
import javax.sql.DataSource;
 
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
 
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
 
public class SpringBoardDAO  implements BoardDAO {
       private JdbcTemplate jdbcTemplate;
 
       public void setDataSource(DataSource dataSource) {
             this.jdbcTemplate = new JdbcTemplate(dataSource);
       }
 
       // /게시판 전체 리스트 보기(list.html)
       public List<BoardDTO> boardList() throws DataAccessException {
             List<BoardDTO> boardList = null;
 
             String sql = "select * from board";
 
             boardList = jdbcTemplate.query(sql, new RowMapper() {
                    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                           BoardDTO board = new BoardDTO();
 
                           board.setSeq(rs.getInt("seq"));
                           board.setName(rs.getString("name"));
                           board.setPasswd(rs.getString("passwd"));
                           board.setTitle(rs.getString("title"));
                           board.setContent(rs.getString("content"));
                           board.setFileName(rs.getString("filename"));
                           board.setRegDate(rs.getString("regdate"));
                           board.setReadCount(rs.getInt("readcount"));
                           board.setReply(rs.getInt("reply"));
                           board.setReply_step(rs.getInt("reply_step"));
                           board.setReply_level(rs.getInt("reply_level"));
 
                           return board;
                    }
             });
 
             return boardList;
       }
 
       // 게시물 본문내용 미리보기(/preView)
       public String preView(String seq) throws DataAccessException {
             String sql = "select * from board where seq = ?";
 
             String preContent = (String) jdbcTemplate.queryForObject(sql,
                           new Object[] { seq }, new RowMapper() {
                                 public Object mapRow(ResultSet rs, int rowNum)
                                              throws SQLException {
                                        return rs.getString("content");
                                 }
                           });
             return preContent;
       }
 
       // 게시판 상세보기, 게시글 읽기
       public BoardDTO readContent(String seq) throws DataAccessException {
             String sql = "select * from board where seq = ?";
 
             BoardDTO boardDTO = (BoardDTO) jdbcTemplate.queryForObject(sql,
                           new Object[] { seq }, new RowMapper() {
                                 public Object mapRow(ResultSet rs, int rowNum)
                                              throws SQLException {
                                        BoardDTO board = new BoardDTO();
 
                                        board.setSeq(rs.getInt("seq"));
                                        board.setName(rs.getString("name"));
                                        board.setPasswd(rs.getString("passwd"));
                                        board.setTitle(rs.getString("title"));
                                        board.setContent(rs.getString("content"));
                                        board.setFileName(rs.getString("filename"));
                                        board.setRegDate(rs.getString("regdate"));
                                        board.setReadCount(rs.getInt("readcount"));
                                        board.setReply(rs.getInt("reply"));
                                        board.setReply_step(rs.getInt("reply_step"));
                                        board.setReply_level(rs.getInt("reply_level"));
 
                                        return board;
                                 }
                           });
             // 조회수 1증가
             this.updateReadCount(new Integer(boardDTO.getSeq()).toString());
 
             return boardDTO;
       }
 
       // 읽은 글의 조회수를 1증가
       public int updateReadCount(String seq) throws DataAccessException {
             String sql = "update board set readcount = nvl(readcount,0) + 1 where seq = ?";
             Object[] obj = { seq };
 
             return jdbcTemplate.update(sql, obj);
       }
 
       // 커맨트 입력
       public int insertComment(CommentDTO commentDTO) throws DataAccessException {
             String sql = "insert into comment_t(seq, name, comm) values (?, ?, ?)";
 
             Object[] obj = { commentDTO.getSeq(), // 게시글순번
                           commentDTO.getName(), // 작성자
                           commentDTO.getComment() }; // 커맨트
 
             return jdbcTemplate.update(sql, obj);
       }
 
       // 커맨트 조회
       public List<CommentDTO> commentList(String seq) throws DataAccessException {
             String sql = "select * from comment_t where seq = ?";
 
             List<CommentDTO> commentList = jdbcTemplate.query(sql,
                           new Object[] { seq }, new RowMapper() {
                                 public Object mapRow(ResultSet rs, int rowNum)
                                              throws SQLException {
                                        CommentDTO commentDTO = new CommentDTO();
                                        commentDTO.setName(rs.getString("name"));
                                        commentDTO.setComment(rs.getString("comm"));
 
                                        return commentDTO;
                                 }
                           });
             return commentList;
       }
 
       // 글쓰기
       public int insertBoard(BoardDTO board) throws DataAccessException {
 
             String sql = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? , sysdate , 0 , board_seq.currval , 0 , 0)";
 
             if (board.getFileName() == null) {
                    Object[] obj = { board.getName(), board.getPasswd(),
                                 board.getTitle(), board.getContent(), "" };
                    return jdbcTemplate.update(sql, obj);
             } else {
                    Object[] obj = { board.getName(), board.getPasswd(),
                                 board.getTitle(), board.getContent(), board.getFileName() };
                    return jdbcTemplate.update(sql, obj);
             }
 
       }
 
       // 게시글 수정
       public int updateBoard(BoardDTO board) throws DataAccessException {
            
             String sql = "update board set  title = ? , content = ? where seq = ?";
             Object[] obj = { 
                                    board.getTitle(),
                                    board.getContent(),
                                    board.getSeq()
                                  };
            
             return jdbcTemplate.update(sql, obj);
       }
 
}
 
 
3.  service 클래스를 만들어 보자.
 
소스 코드 빨강색 부분이 추가된 부분
 
 
[BoardService.java]
 
 
소스 코드 빨강색 부분이 추가된 부분
 
 
package onj.board.service;
 
import java.util.List;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
 
/*
 * 게시판에서 구현할 기능을 인터페이스로 정의
 */
public interface BoardService {
       //게시판 리스트 보기
       public List<BoardDTO> boardList();     
      
       //게시물 미리보기
       public String preView(String seq);
      
       //게시판 본문 내용보기, 게시글 읽기
       public BoardDTO readContent(String seq);
      
       //커맨트 입력
       public int insertComment(CommentDTO commentDTO);
      
       //커맨트 조회
       public List<CommentDTO> commentList(String seq);
      
       //게시글 입력
       public int insertBoard(BoardDTO board);
      
       //게시글 수정
       public int updateBoard(BoardDTO board);
            
}
 
 
[BoardServiceImpl.java]
 
 
package onj.board.service;
 
import java.util.List;
import onj.board.dao.BoardDAO;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
 
public class BoardServiceImpl implements BoardService {
    private BoardDAO boardDAO;
   
    public void setBoardDAO(BoardDAO boardDAO) {
        this.boardDAO = boardDAO;
    }
   
    //게시물 리스트 보기
    public List<BoardDTO> boardList() {
        return boardDAO.boardList();
    }
   
    //게시물 본문 내용 미리보기
    public String preView(String seq) {
        return boardDAO.preView(seq);
    }
 
    //게시글 읽기
       public BoardDTO readContent(String seq) {
             return boardDAO.readContent(seq);
       }
 
       //커맨트 입력
       public int insertComment(CommentDTO commentDTO) {
             return boardDAO.insertComment(commentDTO);
       }
 
       //커맨트 조회
       public List<CommentDTO> commentList(String seq) {
             return boardDAO.commentList(seq);
       }   
      
       //게시글 입력
       public int insertBoard(BoardDTO board) {
             return boardDAO.insertBoard(board);
       }
      
       //게시글 수정
       public int updateBoard(BoardDTO board) {
             return boardDAO.updateBoard(board);
       }
      
      
}
 
 
4.     이번에는 컨트롤러를 수정하자.
소스 코드 빨강색 부분이 추가된 부분
 
 
[BoardMultiController.java]
 
package onj.board.controller;
 
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.service.BoardService;
 
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
 
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
 
/*
 * MultiActionController 비슷하거나 관련있는 로직을 수행하는
 * 다수의 액션을 가지고 있을 사용하는 컨트롤러
 * 연관된 요청(Request) 묶을 용이함
 */
public class BoardMultiController extends MultiActionController {
       private BoardService boardService;
 
       public void setBoardService(BoardService boardService) {
             this.boardService = boardService;
       }
 
       // 게시판 리스트 보기, 페이징 기능은 구현 안함
       public ModelAndView list(HttpServletRequest req, HttpServletResponse res)
                    throws Exception {
 
             ModelAndView mv = new ModelAndView("list", "list",
                           boardService.boardList());
 
             return mv;
       }
 
       // 게시글 읽기
       public ModelAndView read(HttpServletRequest req, HttpServletResponse res)
                    throws Exception {
             String seq = req.getParameter("seq");
 
             ModelAndView mav = new ModelAndView("read", "read",
                           boardService.readContent(seq));
             // 해당 글의 커맨트도 함께 내려 보내자.
             mav.addObject("comments", boardService.commentList(seq));
             return mav;
 
       }
 
       // 커맨트쓰기
       public ModelAndView comment(HttpServletRequest req, HttpServletResponse res) {
 
             String seq = req.getParameter("seq");
 
             CommentDTO commentDTO = new CommentDTO();
             commentDTO.setSeq(seq);
             commentDTO.setName(req.getParameter("name"));
             commentDTO.setComment(req.getParameter("comment"));
 
             boardService.insertComment(commentDTO);
 
             return new ModelAndView("redirect:/read.html?seq=" + seq);
       }
 
       // 새글(게시글) 입력
       public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
                    throws Exception {
 
             MultipartRequest multi = new MultipartRequest(req, "c:\\java\\project\\onjboard1\\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");
       }
      
       // 수정
       public ModelAndView update(HttpServletRequest req, HttpServletResponse res)
                    throws Exception {
 
             String seq = req.getParameter("seq");
             String name = req.getParameter("name");
             String passwd = req.getParameter("passwd");
             String title = req.getParameter("title");
             String content = req.getParameter("content");
            
 
             BoardDTO board = new BoardDTO(name, passwd, title, content, "");
             board.setSeq(Integer.parseInt(seq));
 
             boardService.updateBoard(board);                    
 
             return new ModelAndView("redirect:/read.html?seq=" + req.getParameter("seq"));
       }
 
}
 
 
 
5.     read.jsp를 수정하자.
 
글을 수정한 후에는 수정된 글을 DB에서 다시 읽어와서 다시 read.jsp를 보여준다.
 
[read.jsp]
 
<%@ page contentType="text/html; charset=euc-kr" language="java" errorPage="" %>
<%@ 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>
<title>게시물 읽기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
       function write_ok(){
             writeform.submit();
       }
       function update_ok(){
             document.viewform.action = '/onjboard1/update.html';
             document.viewform.submit();
       }
</script>
</head>
 
<body>
<div style="width:600px;">
<div style="float:enter;">
 
<table width="600" height="420" border="1" align="center">
  <tr height="20"><h2>오엔제이프로그래밍실무교육센터 게시판</h2></tr>
  <form name="viewform" method="post">
  <input type="hidden" name="seq" value="${read.seq}">
  <input type="hidden" name="reply" value="${read.reply}">
  <input type="hidden" name="reply_step" value="${read.reply_step}">
  <input type="hidden" name="reply_level" value="${read.reply_level}">
  <tr>
    <td width="100">* 이름</td>
    <td width="500">: <input name="name" type="text" value="${read.name}" size="50" readonly>
      </td>
  </tr>
  <tr>
    <td>* 제목</td>
    <td>:
    <input name="title" type="text" value="${read.title}" size="50" ></td>
  </tr>
  <tr align="center">
    <td colspan="2"><textarea name="content" cols="80" rows="12" >${read.content}</textarea></td>
  </tr>
  <tr>
    <td>* 파일</td>
    <td>:
                    <c:choose>
                           <c:when test="${read.fileName != null}">
                                 ${read.fileName}                                    
                           </c:when>
                           <c:when test="${read.fileName == null}">
                                 파일 없음
                           </c:when>
                    </c:choose>
       </td>
  </tr>
  <tr>
    <td> </td>
    <td><input name="button" type="button" onClick="location.href='./reply.html?seq=${read.seq}'" value="답변">
|
  <input name="button" type="button" onClick="update_ok()" value="수정">
|
<input name="button" type="button" onClick="location.href='./delete.jsp?seq=${read.seq}'" value="삭제">
|
<input name="button" type="button" onClick="location.href='./list.html'" value="목록"></td>
  </tr>
  </form>
  <tr>
    <td height="99" colspan="2">
    <!-- BoardMultiController comment() 메소드 호출 -->
    <form method="post" action="comment.html">
           <table border="1">
             <tr>          
               <td>이름 : </td>
               <td><input type="text" name="name"></td>
               <td>코멘트:</td>
               <td><input type="text" name="comment"></td>
               <td><input type="submit" name="Button" value="쓰기"></td>
             </tr>
           </table>
           <input type="hidden" name="seq" value="${read.seq}">
    </form>
            <!--  달려있는 커맨트 보기 -->
              <table width="789" border="1">
                  <c:forEach var="comment" items="${comments}">
                               <tr>
                              <td width="42" align="center">*</td>
                              <td width="86">${comment.name}</td>
                              <td width="639">${comment.comment}</td>
                            </tr>
                        </c:forEach>
             </table>
      </td>
    </tr>
   
</table>
<br><br>
<table><tr><td><tr><b>http://www.onjprogramming.co.kr</tr></td></tr></table>
 
 
</div>
</div>
</body>
</html>
 
 
 
 
6.     action-servlet.xml을 수정하자.
 
소스 코드 빨강색 부분이  추가된 부분
 
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
 
       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
             destroy-method="close">
             <property name="driverClassName">
                    <value>oracle.jdbc.driver.OracleDriver</value>
             </property>
             <property name="url">
                    <value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
             </property>
             <property name="username">
                    <value>scott</value>
             </property>
             <property name="password">
                    <value>tiger</value>
             </property>
       </bean>
 
       <!-- 넘어오는 URL 따라 컨트롤러에서 실행될 메소드 매핑 -->
       <!-- PropertiesMethodNameResolver prop key 넘어오는 url 대해 실행할 컨트롤러의 메소드
             정의 -->
       <bean id="userControllerMethodNameResolver"
              class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
             <property name="mappings">
                    <props>
                           <!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
                           <prop key="/list.html">list</prop>
                          
                           <!-- read.html 요청이 오면 컨트롤러의 read 메소드 실행 -->
                           <prop key="/read.html">read</prop>
                          
                           <!-- comment.html 요청이 오면 컨트롤러의 comment 메소드 실행 -->
                           <prop key="/comment.html">comment</prop>
                          
                           <!-- write.html 요청이 오면 컨트롤러의 write 메소드 실행 -->
                           <prop key="/write.html">write</prop>
                          
                           <!-- update.html 요청이 오면 컨트롤러의 update 메소드 실행 -->
                           <prop key="/update.html">update</prop>                                  
                    </props>
             </property>
       </bean>
 
       <!-- 리졸버 -->
       <bean id="viewResolver"
             class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             <property name="prefix">
                    <value>/jsp/</value>
             </property>
             <property name="suffix">
                    <value>.jsp</value>
             </property>
       </bean>
 
       <!-- 컨트롤러 매핑 -->
       <bean name="/list.html /read.html /comment.html /write.html /update.html"
                       class="onj.board.controller.BoardMultiController">
             <property name="methodNameResolver">
                    <ref local="userControllerMethodNameResolver" />
             </property>
             <property name="boardService">
                    <ref bean="boardService" />
             </property>
       </bean>
      
</beans>
 
 
 
실행결과 및 현재까지 만들어진 이클립스 구조
(게시판 리스트보기 + 게시물 본문내용 미리 보기 + 게시글 상세보기 + 커멘트기능 + 글쓰기 + 글 수정하기)
 
 
:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
 
 
 
 
 
 
 
 
 
 
 








댓글 없음:

댓글 쓰기