Spring – MyBATIS 게시판 만들기 – 3

Spring framework 예제

Spring 을 이용한 게시판에 관련한 DTO, DAO 작성하기, View Page 만들기, Controller 만들기

Spring Framework
Spring Framework

1, 2 에서 Spring Framework와 MyBATIS 기초적인 설정과 회원과 관련된 작업을 마쳤다. 이제 클라이언트가 로그인을 한 후 게시판 기능을 사용할 수 있도록 작성하면 끝난다.

 

게시판 Database Table 만들기

Column Name DataType Option
 BNO  number(7) Primary key
 ID  varchar2(20)  Foreign key
 TITLE  varchar2(50) not null
 CONTENT  long not null
 REGIST  date  default SYSDATE
 HIT  number(6)  default 0

게시판에 필요한 기능은 위와 같다. 제목과 내용이 들어갈 것이며 작성시간과 작성자, 조회수가 필요하고 게시판의 제목을 눌렀을 때 해당 게시물에 내용을 끌어오기 위해 게시물을 구별하는 PK도 필요하다.

 

게시물 DTO, DAO 만들기

데이터베이스 테이블을 정의했다면 DTO를 만들고 DAO를 만들기 전 MyBATIS의 Mapper파일에 SQL문을 정의한 후 DAO를 만들면 Model부분은 끝이난다.

게시판(Board.java) DTO의 코드는 다음과 같다.

package com.board.dto;

import org.springframework.stereotype.Repository;

@Repository
public class Board {
    private String bno;
    private String id;
    private String title;
    private String content;
    private String regist;
    private int hit;
    
    public String getBno() {
        return bno;
    }
    public void setBno(String bno) {
        this.bno = bno;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getRegist() {
        return regist;
    }
    public void setRegist(String regist) {
        this.regist = regist;
    }
    public int getHit() {
        return hit;
    }
    public void setHit(int hit) {
        this.hit = hit;
    }
}

 

DTO 정의 후 MyBATIS Mapper SQL을 사용하여 정의하고 소스는 다음과 같다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Board">
    <select id="get" resultType="com.board.dto.Board" parameterType="string">
        SELECT bno, id, title, content, regist, hit
        FROM board
        WHERE bno=#{bno}
    </select>
    
    <select id="getAll" resultType="com.board.dto.Board">
        SELECT bno, id, title, content, regist, hit
        FROM board
        ORDER BY regist DESC
    </select>
    
    <select id="getHit" resultType="int" parameterType="string">
        SELECT hit FROM board WHERE bno = #{bno}
    </select>
    
    <insert id="add" parameterType="com.board.dto.Board">
        INSERT INTO board
        VALUES ( board_seq.nextval, #{id}, #{title}, #{content}, default, default )
    </insert>
    
    <update id="modContent" parameterType="com.board.dto.Board">
        UPDATE board
        SET title = #{title}, content = #{content}
        WHERE bno = #{bno}
    </update>
    
    <update id="modHit" parameterType="com.board.dto.Board">
        UPDATE board
        SET hit = #{hit}
        WHERE bno = #{bno}
    </update>
    
    <delete id="del" parameterType="string">
        DELETE FROM board
        WHERE bno = #{bno}
    </delete>

</mapper>

 

마지막으로 DAO를 정의하면 된다.

package com.board.dao;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.board.dto.Board;

@Repository
public class BoardDAO {
    @Inject
    SqlSession sql;
    
    public void insert(Board board) {
        sql.insert("Board.add", board);
    }
    public void update(Board board) {
        sql.update("Board.modContent", board);
    }
    public void incrementHit(Board board) {
        String bno = board.getBno();
        int count = sql.selectOne("Board.getHit", bno);
        count++;
        board.setHit(count);        
        sql.update("Board.modHit", board);
    }
    public void delete(String bno) {
        sql.delete("Board.del", bno);
    }
    public Board select(String bno) {
        return sql.selectOne("Board.get", bno);
    }
    public List<Board> selectAll() {
        return sql.selectList("Board.getAll");
    }
}

 

게시판 관련 View Page(JSP) 만들기

글쓴이는 크게 게시판 리스트, 게시물 확인, 게시물 작성, 게시물 수정 총 네 개의 페이지를 만들었다.

게시판 리스트를 확인하는 board.jsp 소스는 다음과 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>
    a {
        text-decoration: none;
    }
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 style="text-align: center;">Board</h1><h4 style="text-align:center;">${sessionScope.name } 환영합니다.</h4>
    <input type="button" value="로그아웃" onclick="window.location.assign('Logout')" />
    <hr>
    <table style="width: 100%;">
        <tr>
            <td width=10%>No</td>
            <td width=15%>아이디</td>
            <td width=50%>제목</td>
            <td width=15%>등록일</td>
            <td width=10%>조회수</td>
        </tr>
        <c:forEach items="${board}" var="a">
            <tr>
                <td width=10%>${a.bno}</td>
                <td width=15%>${a.id}</td>
                <td width=50%><a href="Get?bno=${a.bno}">${a.title}</a></td>
                <td width=15%>${a.regist}</td>
                <td width=10%>${a.hit}</td>
            </tr>
        </c:forEach>
    </table>
    <hr>
    <input type="button" onclick="window.location.assign('WriteForm')" value="작성하기" />
</body>
</html>

컨트롤러에서 “model”을 사용하여 Attribute를 추가할 것이다. 이는 일반 Dynamic Web Project에서 request.setAttribute()와 같은 역할이다.

 

게시물을 클릭하면 볼 페이지 content.jsp 는 다음과 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 style="text-align:center;">${board.title}</h1>
    <hr>
    <p>${board.content }<p>
    <hr>
    글쓴이 : ${board.id}<br>
    작성시간 : ${board.regist}<br>
    <input type=button value=수정하기 onclick="window.location.assign('UpdateForm?bno=${board.bno}')" />
    <input type=button value=삭제하기 onclick="window.location.assign('Delete?bno=${board.bno}')" />

</body>
</html>

 

작성하는 페이지 write.jsp 는 다음과 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
    function check() {
        if ( !document.writeform.title.value ) {
            alert("제목을 입력해주세요");
            return;
        } else if ( !document.writeform.content.value ) {
            alert("내용을 입력해주세요");
            return;
        }
        
        document.writeform.submit();
    }
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action=Write method=post name=writeform>
        제목 : <input type="text" size=50 value="${board.title}" name=title placeholder="제목을 입력해주세요" />
        <hr>
        <textarea style="width: 395px; height: 230px;" name=content>${board.content}</textarea>
        <input type=button onclick="check();" value="작성하기" />
    </form>
    <hr>
    글쓴이 : ${sessionScope.id}

</body>
</html>

 

마지막으로 수정하는 페이지 update.jsp 는 다음과 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
    function check() {
        if ( !document.writeform.title.value ) {
            alert("제목을 입력해주세요");
            return;
        } else if ( !document.writeform.content.value ) {
            alert("내용을 입력해주세요");
            return;
        }
        
        document.writeform.submit();
    }
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action=Update method=post name=writeform>
        <input type=hidden value="${board.bno}" name="bno" />
        제목 : <input type="text" size=50 value="${board.title}" name=title placeholder="제목을 입력해주세요" />
        <hr>
        <textarea style="width: 395px; height: 230px;" name=content>${board.content}</textarea>
        <input type=button onclick="check();" value="작성하기" />
    </form>
    <hr>
    글쓴이 : ${sessionScope.id}

</body>
</html>

 

컨트롤러 만들기

Spring Framework에서는 모든 요청을 DispatcherServlet이 받고 이 서블릿이 해당 요청을 ‘@’ Annotation으로 정의된 곳으로 알아서 매핑시킨다. 이 때 사용하는 @Controller와 @RequestMapping이 된다.

package com.board.controller;

import java.io.IOException;
import java.util.List;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.board.dao.BoardDAO;
import com.board.dto.Board;

@Controller
public class BoardController {
    final static private Logger logger = LoggerFactory.getLogger(BoardController.class);

    @Inject
    BoardDAO bdao;
    
    @RequestMapping( value = "GetList", method = RequestMethod.GET )
    public String outList(Model model) {
        logger.info("게시판 첫 페이지");
        List<Board> board  = bdao.selectAll();
        model.addAttribute("board", board);
        
        return "board/board";
    }
    
    @RequestMapping( value = "Get", method = RequestMethod.GET)
    public String getBoard( Model model, @RequestParam("bno") String bno ) {
        logger.info("게시물 클릭");
        Board board = bdao.select(bno);
        bdao.incrementHit(board);
        model.addAttribute("board", board);
        
        return "board/content";
    }
    
    @RequestMapping( value = "WriteForm" )
    public String writeForm() {
        logger.info("게시물 작성 클릭");
        return "board/write";
    }
    
    @RequestMapping ( value = "Write", method = RequestMethod.POST)
    public void write( Model model, Board board, HttpServletRequest req, HttpServletResponse res ) throws IOException {
        logger.info("작성");
        HttpSession session = req.getSession();
        String id = (String)session.getAttribute("id");
        board.setId(id);
        
        bdao.insert(board);
        res.sendRedirect("GetList");
    }
    
    @RequestMapping( value = "Delete", method = RequestMethod.GET ) 
    public String delete ( Model model, @RequestParam("bno") String bno ) {
        logger.info("게시물 삭제");
        bdao.delete(bno);
        
        List<Board> board = bdao.selectAll();
        model.addAttribute("board", board);
        return "board/board";
    }
    
    @RequestMapping( value = "Update", method = RequestMethod.POST)
    public String update( Model model, Board reqBoard ) {
        bdao.update(reqBoard);
        
        List<Board> board = bdao.selectAll();
        model.addAttribute("board", board);
        return "board/board";
    }
    
    @RequestMapping( value = "UpdateForm", method = RequestMethod.GET)
    public String updateForm( Model model, @RequestParam("bno") String bno ) {
        Board board = bdao.select(bno);
        model.addAttribute("board", board);
        return "board/update";
    }
}

여기까지 내용을 이클립스에서 확인하고 싶다면 다음을 눌러 파일을 다운받아 Import시킨다. war파일

 

앞으로 해야할 일들 (Spring setup)

예외 처리, 로그인 세션 처리, MultipartRequest 사용해서 이미지 업로드 받기, Spring Security를 이용한 인증, 권한부여 등 보안관련 설정, POI를 이용하여 .xls 파일 만들고 ViewResolver로 통해 해당 엑셀 파일을 다운받을 수 있게 하기, DB Object(Model)을 만들어 MyBATIS를 이용하여 DB 통신, 리눅스의 crontab 과 같이 설정된 주기에 따라 메서드를 실행시키는 Tasker, RestfulController 등

%d 블로거가 이것을 좋아합니다: