2013년 7월 30일 화요일

13. [스프링게시판만들기]커멘트 조회, 입력기능 추가(Spring Framework3.2 Board) ,자바,오라클실무교육학원 오엔제이프로그래밍실무학원

기존 게시판 기능 + Spring 게시판 구현(커멘트 조회, 입력 기능추가)


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




1.     시작하기
-       이번에는 게시판 상세보기(글읽기) 페이지에서 게시글에 커멘트를 입력하고, 입력되어 있는 커멘트를  글을 게시글 조회 시 같이 조회될 수 있는 기능을 추가해 보자.
2.     먼저 커멘트(Comment) 처리를 위한 CommentDTO.java를 작성하자.
[CommentDTO.java]
package onj.board.model;
public class CommentDTO {
       public int seq;       //게시글 번호
       public String name;   //이름
       public String comment;//커멘트
      
       public CommentDTO() {}
      
       public CommentDTO(String name, String comment) {
             this.name = name;
             this.comment = comment;
       }
      
       public int getSeq() {
             return seq;
       }
       public void setSeq(int seq) {
             this.seq = seq;
       }
       public String getName() {
             return name;
       }
       public void setName(String name) {
             this.name = name;
       }
       public String getComment() {
             return comment;
       }
       public void setComment(String comment) {
             this.comment = comment;
       }     
}
3.     먼저 커멘트(Comment) 처리를 위한 DAO쪽 클래스를 작성하자.
BoardDAO.java 인터페이스, SpringBoardDAO.java 클래스에 커멘트 입력, 조회를 위한 insertComment(), commentList() 두개의 메소드를 추가하자.
[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;
}
[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;
       }
}
4.  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);
}
[SpringServiceImpl.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);
       }   
}
5.     이번에는 컨트롤러를 수정하자.
조금 달라진 부분은 게시 글을 읽을 때 해당 글의 커멘트도 같이 화면에 보일 수 있도록 뷰에 커멘트 리스트를 매달아서(addObject해서) 보낸다.
[BoardMultiController.java]
소스 코드 빨강색 부분이 커멘트 조회, 입력 기능을 위해 추가된 부분
package onj.board.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
/*
 * 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);
           }
          
}
6.     커멘트 기능이 추가된 뷰페이지 read.jsp를 작성하자.
소스 코드 빨강색 부분이 커멘트 조회, 입력 기능을 위해 추가된 부분
[read.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java" import="java.sql.*" errorPage="" %>
<%@ page import = "onj.board.model.* , onj.board.service.* , java.util.*" %>
<%@ 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();
       }
</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>
  <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" readonly></td>
  </tr>
  <tr align="center">
    <td colspan="2"><textarea name="content" cols="80" rows="12" readonly>${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" 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>
  <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>
<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}">
</div>
</div>
</body>
</html>
7.     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>                         
                    </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" 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" />




>

댓글 없음:

댓글 쓰기