티스토리 뷰

BACK-END/SPRING

[SPRING] MVC 게시판

진심스테이크 2019. 9. 25. 16:00

 

DAO : 데이터 베이스 연동

Mapper : Query문

DTO : 모델

Service : 비즈니스 로직

Controller 

Views : JSP

 

구조

 

BoardController.java

package com.project.controller;

import java.util.List;
import java.util.Map;

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

import com.board.db.BoardDTO;
import com.board.service.BoardService;
import com.board.service.Criteria;
import com.board.service.Paging;

@Controller
@RequestMapping("/board")
public class BoardController {

	@Autowired
	private BoardService service;

	// 게시판 목록
	@RequestMapping("/list")
	public String boardList(BoardDTO dto, Model model, Criteria cri) throws Exception {
		Paging paging = new Paging();
		paging.setCri(cri);
		paging.setTotalCount(service.boardListCnt(dto));

		int pageNum = paging.getCri().getPage();

		List<Map<String, Object>> list = service.listAll(cri);

		model.addAttribute("boardList", list);
		model.addAttribute("pageNum", pageNum);
		model.addAttribute("paging", paging);
		return "/board/BoardList";
	}

	// 글 읽기
	@RequestMapping("/detail")
	public ModelAndView boardDetail(@RequestParam int no) throws Exception {
		service.boardHit(no);
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/board/BoardDetail");
		mav.addObject("boardDetail", service.boardDetail(no));
		return mav;
	}

	// 글 삭제
	@RequestMapping("/delete")
	public String boardDelete(@RequestParam int no) throws Exception {
		service.boardDelete(no);
		return "redirect:/board/list";
	}

	// 글 작성 페이지
	@RequestMapping("/writePage")
	public String boardWritePage() {
		return "/board/BoardWrite";
	}

	// 글 작성
	@RequestMapping("/write")
	public String boardWrite(@ModelAttribute BoardDTO dto) throws Exception {
		service.boardWrite(dto);
		return "redirect:/board/list";
	}

	// 글 수정 페이지
	@RequestMapping("/editPage")
	public ModelAndView boardEditPage(@RequestParam int no) throws Exception {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/board/BoardEdit");
		mav.addObject("boardEdit", service.boardDetail(no));
		return mav;
	}

	// 글 수정
	@RequestMapping("/edit")
	public String boardEdit(@ModelAttribute BoardDTO dto) throws Exception {
		service.boardEdit(dto);
		return "redirect:/board/detail?no=" + dto.getNo();
	}
}

 

 

BoardService.java / BoardServiceImpl.java

package com.board.service;

import java.util.List;
import java.util.Map;

import com.board.db.BoardDTO;

public interface BoardService {
	
	// 게시판 목록
	public List<BoardDTO> boardList() throws Exception;

	// 글 읽기
	public BoardDTO boardDetail(int no) throws Exception;

	// 글 조회수
	public void boardHit(int no) throws Exception;

	//글 삭제
	public void boardDelete(int no) throws Exception;

	// 글 작성
	public void boardWrite(BoardDTO dto) throws Exception;

	// 글 수정
	public void boardEdit(BoardDTO dto) throws Exception;

	// 페이징 처리
	public List<Map<String, Object>> listAll(Criteria cri) throws Exception;

	// 글 갯수
	public int boardListCnt(BoardDTO dto) throws Exception;
}

 

package com.board.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.board.db.BoardDAO;
import com.board.db.BoardDTO;

@Service
public class BoardServiceImpl implements BoardService {

	@Autowired
	private BoardDAO dao;

	@Override
	public List<BoardDTO> boardList() throws Exception {
		return dao.boardList();
	}

	@Override
	public BoardDTO boardDetail(int no) throws Exception {
		return dao.boardDetail(no);
	}

	@Override
	public void boardHit(int no) throws Exception {
		dao.boardHit(no);
	}

	@Override
	public void boardDelete(int no) throws Exception {
		dao.boardDelete(no);
	}

	@Override
	public void boardWrite(BoardDTO dto) throws Exception {
		String title = dto.getTitle();
		String content = dto.getContent();
		String id = dto.getId();

		dto.setTitle(title);
		dto.setContent(content);
		dto.setId(id);

		dao.boardWrite(dto);
	}

	@Override
	public void boardEdit(BoardDTO dto) throws Exception {
		dao.boardEdit(dto);
	}

	@Override
	public List<Map<String, Object>> listAll(Criteria cri) throws Exception {
		return dao.listAll(cri);
	}

	@Override
	public int boardListCnt(BoardDTO dto) throws Exception {
		return dao.boardListCnt(dto);
	}

}

 

 

BoardDAO.java / BoardDAOImpl.java

package com.board.db;

import java.util.List;
import java.util.Map;

import com.board.service.Criteria;

// DB 연동
public interface BoardDAO {
	public List<BoardDTO> boardList() throws Exception;

	public BoardDTO boardDetail(int no) throws Exception;

	public void boardHit(int no) throws Exception;

	public void boardDelete(int no) throws Exception;

	public void boardWrite(BoardDTO dto) throws Exception;

	public void boardEdit(BoardDTO dto) throws Exception;

	public List<Map<String, Object>> listAll(Criteria cri) throws Exception;

	public int boardListCnt(BoardDTO dto) throws Exception;
}

 

package com.board.db;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.board.service.Criteria;

@Repository
public class BoardDAOImpl implements BoardDAO {

	@Autowired
	private SqlSession sqlSession;

	private static final String nameSpace = "com.board.mappers.boardMapper";

	@Override
	public List<BoardDTO> boardList() throws Exception {
		return sqlSession.selectList(nameSpace + ".boardList");
	}

	@Override
	public BoardDTO boardDetail(int no) throws Exception {
		return sqlSession.selectOne(nameSpace + ".boardRead", no);
	}

	@Override
	public void boardHit(int no) throws Exception {
		sqlSession.update(nameSpace + ".boardHit", no);
	}

	@Override
	public void boardDelete(int no) throws Exception {
		sqlSession.update(nameSpace + ".boardDelete", no);
	}

	@Override
	public void boardWrite(BoardDTO dto) throws Exception {
		sqlSession.insert(nameSpace + ".boardWrite", dto);
	}

	@Override
	public void boardEdit(BoardDTO dto) throws Exception {
		sqlSession.update(nameSpace + ".boardEdit", dto);
	}

	@Override
	public List<Map<String, Object>> listAll(Criteria cri) throws Exception {
		return sqlSession.selectList("listAll", cri);
	}

	@Override
	public int boardListCnt(BoardDTO dto) throws Exception {
		return sqlSession.selectOne(nameSpace + ".baordListCnt", dto);
	}

}

 

 

BoardDTO (model)

package com.board.db;

// 데이터 model
public class BoardDTO {
	private int no;
	private String title;
	private String content;
	private String date;
	private String id;
	private int hit;

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	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 getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public int getHit() {
		return hit;
	}

	public void setHit(int hit) {
		this.hit = hit;
	}

}

 

 

BoardMapper.xml

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

<mapper namespace="com.board.mappers.boardMapper">

	<select id="boardList" resultType="BoardDTO">
		SELECT * from board
	</select>

	<select id="boardRead" resultType="BoardDTO">
		SELECT * from board WHERE
		no=#{no}
	</select>

	<update id="boardHit">
		UPDATE board SET hit = hit+1 WHERE no=#{no}
	</update>

	<delete id="boardDelete">
		DELETE from board WHERE no=#{no}
	</delete>

	<insert id="boardWrite">
		INSERT INTO board (title, content, date, id, hit)
		values (#{title}, #{content}, now(), #{id}, 0)
	</insert>

	<update id="boardEdit">
		UPDATE board SET title=#{title}, content=#{content},
		date=now() WHERE no=#{no}
	</update>

	<select id="listAll" resultType="hashMap">
		SELECT * from board ORDER BY no DESC LIMIT #{pageStart}, #{perPageNum}
	</select>
	
	<select id="baordListCnt" resultType="int">
		SELECT COUNT(*) as boardCnt from board
	</select>

</mapper>

 

 

페이징 처리

Criteria

package com.board.service;

public class Criteria {
	private int page;
	private int perPageNum;

	public Criteria() {
		this.page = 1;
		this.perPageNum = 10;
	}

	public int getPageStart() {
		return (this.page - 1) * perPageNum;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		if (page <= 0)
			this.page = 1;
		else {
			this.page = page;
		}
	}

	public int getPerPageNum() {
		return perPageNum;
	}

	public void setPerPageNum(int pageCount) {
		int cnt = this.perPageNum;
		if (pageCount != cnt) {
			this.perPageNum = cnt;
		} else {
			this.perPageNum = pageCount;
		}
	}
}

 

Paging

package com.board.service;

public class Paging {
	private Criteria cri;
	private int totalCount;
	private int startPage;
	private int endPage;
	private boolean prev;
	private boolean next;
	private int displayPageNum = 10;

	public Criteria getCri() {
		return cri;
	}

	public void setCri(Criteria cri) {
		this.cri = cri;
	}

	public int getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
		calcData();
	}

	private void calcData() {
		endPage = (int) (Math.ceil(cri.getPage() / (double) displayPageNum) * displayPageNum);
		int tempEndPage = (int) (Math.ceil(totalCount / (double) cri.getPerPageNum()));

		if (endPage > tempEndPage) {
			endPage = tempEndPage;
		}

		startPage = (endPage - displayPageNum) + 1;
		if (startPage <= 0)
			startPage = 1;

		prev = startPage == 1 ? false : true;
		next = endPage * cri.getPerPageNum() >= totalCount ? false : true;
	}

	public int getStartPage() {
		return startPage;
	}

	public void setStartPage(int startPage) {
		this.startPage = startPage;
	}

	public int getEndPage() {
		return endPage;
	}

	public void setEndPage(int endPage) {
		this.endPage = endPage;
	}

	public boolean isPrev() {
		return prev;
	}

	public void setPrev(boolean prev) {
		this.prev = prev;
	}

	public boolean isNext() {
		return next;
	}

	public void setNext(boolean next) {
		this.next = next;
	}

	public int getDisplayPageNum() {
		return displayPageNum;
	}

	public void setDisplayPageNum(int displayPageNum) {
		this.displayPageNum = displayPageNum;
	}
}

 


 

Views

- 무조건 views 경로 안에 있어야함

 

servlet-context.xml

<resources mapping="/resources/**" location="/resources/" />

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<beans:property name="prefix" value="/WEB-INF/views/" />
	<beans:property name="suffix" value=".jsp" />
</beans:bean>
	
<context:component-scan base-package="com.*" />

 

 

BoardList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Board List</title>
</head>

<body>
    <jsp:include page="/WEB-INF/views/template/header.jsp" />

    <div>
        <h1>Board List</h1>
        <c:if test="${sessionScope.id != null}">
            <div style="float: right;">
                <button type="button" onclick="location.href='./writePage'">글쓰기</button>
                <button type="button" onclick="location.href='/'">Main</button>
            </div>
        </c:if>
        <c:if test="${sessionScope.id eq null }">
            <div style="float: right;">
                <button type="button" onclick="location.href='/'">Main</button>
            </div>
        </c:if>
        <div>
            <div>
                <table>
                    <thead>
                        <tr align="center">
                            <th scope="col">번호</th>
                            <th scope="col">작성자</th>
                            <th scope="col">제목</th>
                            <th scope="col">날짜</th>
                            <th scope="col">조회수</th>
                        </tr>
                    </thead>
                    <tbody>
                        <c:forEach items="${boardList}" var="boardList">
                            <tr align="center">
                                <td scope="row">${boardList.no}</td>
                                <td scope="row">${boardList.id}</td>
                                <td scope="row"><a href="/board/detail?no=${boardList.no}">${boardList.title}</a></td>
                                <td scope="row">${boardList.date}</td>
                                <td scope="row">${boardList.hit}</td>
                            </tr>
                        </c:forEach>
                    </tbody>
                </table>
            </div>
            <ul style="margin: auto;">
                <c:if test="${paging.prev }">
                    <li>
                        <a href='<c:url value="/board/list?page=${paging.startPage-1 }"/>'>
                            <i class="fa fa-chevron-left"></i>
                        </a></li>
                </c:if>
                <c:forEach begin="${paging.startPage }" end="${paging.endPage }" var="idx">
                    <c:choose>
                        <c:when test="${paging.cri.page eq idx}">
                            <li><b>
                                    <a href='<c:url value="/board/list?page=${idx }"/>'>
                                        <i class="fa">${idx }&nbsp;</i></a></b></li>
                        </c:when>
                        <c:otherwise>
                            <li>
                                <a href='<c:url value="/board/list?page=${idx }"/>'>
                                    <i class="fa">${idx }&nbsp;</i></a></li>
                        </c:otherwise>
                    </c:choose>
                </c:forEach>
                <c:if test="${paging.next && paging.endPage >0 }">
                    <li>
                        <a href='<c:url value="/board/list?page=${paging.endPage+1 }"/>'>
                            <i class="fa fa-chevron-right"></i>
                        </a></li>
                </c:if>
            </ul>
        </div>
    </div>
</body>

</html>

 

 

BoardWrite.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Board Write</title>
</head>

<body>
    <jsp:include page="/WEB-INF/views/template/header.jsp" />
    <br>
    <div style="float: none; margin: 0 auto;">

        <h1 class="display-4" align="center">Board Write</h1>
        <form method="post" action="/board/write">
            <div>
                <h6>작성자</h6>
                <input type="text" value="${sessionScope.id}" name="id" readonly>
                <h6>제목</h6>
                <input type="text" placeholder="title" required name="title">
                <h6>내용</h6>
                <textarea type="textarea" placeholder="내용" required name="content"></textarea>
            </div>

            <div align="center">
                <button type="submit">확인</button>
                <button type="button" onclick="location.href='/board/list'">뒤로</button>
            </div>
        </form>
    </div>
</body>

</html>

 

 

BoardDetail.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>
<html>

<head>
    <meta charset="UTF-8">
    <title>Board Read</title>
</head>

<body>
    <jsp:include page="/WEB-INF/views/template/header.jsp" />
    <div style="float: none; margin: 0 auto;">
        <h1 class="display-4" align="center">Board Detail</h1>
        <div>
            <h6>글번호</h6>
            <input name="id" type="text" value="${boardDetail.no}" readonly>
            <h6>조회수</h6>
            <input type="text" value="${boardDetail.hit}" readonly name="hit">
            <h6>작성자</h6>
            <input type="text" value="${boardDetail.id}" name="id" readonly>
            <h6>제목</h6>
            <input type="text" value="${boardDetail.title}" name="title" readonly>
            <h6>내용</h6>
            <textarea type="textarea" name="content" readonly>${boardDetail.content}</textarea>
            <h6>날짜</h6>
            <input type="text" name="date" value="${boardDetail.date}" readonly>

            <c:if test="${sessionScope.id eq boardDetail.id }">
                <button type="button" onclick="location.href='/board/editPage?no=${boardDetail.no}'">수정</button>
                <button type="button" onclick="location.href='/board/delete?no=${boardDetail.no}'">삭제</button>
            </c:if>

            <button type="button" onclick="location.href='/board/list'">뒤로</button>
        </div>
    </div>
</body>

</html>

 

 

BoardEdit.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Board Edit</title>

    <head>
        <title>MVC 게시판</title>
    </head>

<body>
    <jsp:include page="/WEB-INF/views/template/header.jsp" />

    <div style="float: none; margin: 0 auto;">
        <h1 class="display-4" align="center">Board Edit</h1>
        <form action="/board/edit" method="post">
            <input type="hidden" name="no" value="${boardEdit.no}"></input>
            <div>
                <h6>작성자</h6>
                <input type="text" value="${boardEdit.id}" name="id" readonly>
                <h6>제목</h6>
                <input type="text" value="${boardEdit.title}" name="title">
                <h6>내용</h6>
                <textarea type="textarea" name="content">${boardEdit.content}</textarea>
                <h6>날짜</h6>
                <input type="text" value="${boardEdit.date}" name="date" readonly>
            </div>

            <div align="center">
                <button type="submit">수정</button>
                <button type="button" onclick="location.href='/board/detail?no=${boardEdit.no}'">뒤로</button>
            </div>
        </form>
    </div>
</body>

</html>

 

'BACK-END > SPRING' 카테고리의 다른 글

[SPRING] LOGIN MVC  (1) 2019.09.26
[SPRING] MYBATIS MYSQL 연동  (0) 2019.09.25
[SPRING] IoC - SPRING CONTAINER  (0) 2019.09.25
[SPRING] AOP - 관점 지향 프로그래밍  (0) 2018.05.17
[SPRING] FRAMEWORK  (0) 2018.05.15
댓글