다가오는 다음을 향해

[Spring MVC] 게시판 구현 본문

국비학원 공부노트/Spring MVC

[Spring MVC] 게시판 구현

hyeseo 2022. 4. 13. 23:32

[ 개발환경 ]
MacBook Air M1 2020년형 
eclipse [2021-3 var]
Java [zulu-8]
JSP
Tomcat [Apache Tomcat/9.0.58]

[ version ]
- springframework - 4.3.14
- aspectj - 1.8.9
- Test - 4.12

Maven repository
- mysql-connector-java  8.0.27
- spring-jdbc - 4.3.14
- spring-test - 4.3.14

mybatis - 3.4.4
mybatis-spring - 1.3.1


 

 

게시판 설계 및 구현

 

게시판 구현 Work


 

  1. table 설계
  2. boardDTO 작성
  3. boardMapper.xml
  4. BoardDAO.java  / BoardDAOImpl.java
  5. BoardService.java  /BoardServiceImpl.java
  6. BoardController.java

 

테이블 설계


Table: board
글번호 bno int(11) PK AI
제목 title varchar(45) not null
내용 content varchar(45) not null
아이디 id varchar(45) not null
작성일 regdate datetime
조회수 readcnt int(11)
비고 etc varchar(45)

 

 

boardDTO


BoardDTO.java

package kr.co.dong.board;

public class BoardDTO {

	private int bno; // 글번호
	private String title; // 글제목
	private String content; // 내용
	private String id; // 아이디
	private String regdate; // 등록일
	private int readcnt; //조회수
	private String etc; // 비고

	public int getBno() {
		return bno;
	}

	public void setBno(int bno) {
		this.bno = bno;
	}

	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 getId() {
		return id;
	}

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

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public int getReadcnt() {
		return readcnt;
	}

	public void setReadcnt(int readcnt) {
		this.readcnt = readcnt;
	}

	public String getEtc() {
		return etc;
	}

	public void setEtc(String etc) {
		this.etc = etc;
	}

	@Override
	public String toString() {
		return "BoardDTO [bno=" + bno + ", title=" + title + ", content=" + content + ", id=" + id + ", regdate="
				+ regdate + ", readcnt=" + readcnt + ", etc=" + etc + "]";
	}
	
}



 

boardMapper.xml


boardMapper를 작성하기 전

mybatis-config.xml에 boardType의 별칭을 설정한다.

 

mybatis-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 alias="Board" type="kr.co.dong.board.BoardDTO"/>
	</typeAliases>
</configuration>

 

Mybatis의 SqlSession을 호출하는 XML 매핑구문을 작성한다. (SqlSessionFactory)

boardMapper.xml
글 전체목록 <select id="boardList" resultType="Board">
select * from board
</select>
글 상세보기 <select id="getBoard"  parameterType="java.lang.Integer" resultType="Board">
select * from board where bno=#{bno}
</select>
글 조회수 업데이트 <update id="readcount" parameterType="java.lang.Integer">
update board set readcnt = readcnt + 1 where bno = #{bno}
</update>
글 추가하기 <insert id="registerBoard" parameterType="Board">
insert into board (bno, title, content, id, regdate, readcnt, etc)
values ( #{bno}, #{title},  #{content}, #{id}, now(), #{readcnt}, #{etc})
</insert>
글 수정하기 <update id="modifyBoard" parameterType="Board" >
update board
<set>
<if test="title != null">title=#{title},</if>
<if test="content != null">content=#{content}</if>
</set>
where bno=#{bno}
</update>
글 삭제하기 <delete id="deleteBoard" parameterType="java.lang.Integer">
delete from board where bno=#{bno}
</delete>

 

boardMapper.xml

<?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="kr.co.dong.boardMapper">

	<!-- 글 전체목록-->
	<select id="boardList" resultType="Board">
		select * from board		
	</select>	
	
	<!-- 글 상세보기-->
	<select id="getBoard"  parameterType="java.lang.Integer" resultType="Board">
		select * from board where bno=#{bno}
	</select>
	
	<!--글 등록하기-->
	<insert id="registerBoard" parameterType="Board">
		insert into board (bno, title, content, id, regdate, readcnt, etc)
		values ( #{bno}, #{title},  #{content}, #{id}, now(), #{readcnt}, #{etc})
	</insert>	
	
	<!--글 수정하기-->
	<update id="modifyBoard" parameterType="Board" >
		update board
		<set>
		<if test="title != null">title=#{title},</if>
		<if test="content != null">content=#{content}</if>
		</set>
		where bno=#{bno}
	</update>
	
	<!--글 삭제하기-->
	<delete id="deleteBoard" parameterType="java.lang.Integer">
		delete from board where bno=#{bno}
	</delete>
	
	<!-- 조회수 업데이트 -->
	<update id="readcount" parameterType="java.lang.Integer">
		update board set readcnt = readcnt + 1 where bno = #{bno}
	</update>
    
</mapper>

 

 

BoardDAO.java/BoardDAOImpl.java


Mybatis로 작성한 SqlSessionFactory에서 인터페이스를 호출하기 때문에

boardDAO interface와 boardDAO를 implements한 boardDAOImpl 를 작성한다.

 

BoardDAO.java

package kr.co.dong.board;

import java.util.List;

public interface BoardDAO {

	// 글 전체목록
	public List<BoardDTO> boardList();
	
	// 글 상세보기	
	public BoardDTO getBoard(int bno);
	
	// 글 등록하기
	public int registerBoard(BoardDTO boardDTO);
	
	// 글 수정하기
	public int modifyBoard(BoardDTO boardDTO);
	
	// 글 삭제하기
	public int deleteBoard(int bno);
	
	// 글 조회수증가
	public int updateReadcnt(int bno);

}

 

 

BoardDAOImpl.java

package kr.co.dong.board;

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

import javax.inject.Inject;

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

@Repository //DB나 파일같은 외부 I/O 작업을 처리
public class BoardDAOImpl implements BoardDAO {
	
	@Inject // 주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입한다.
	private SqlSession sqlSession;
	
	private static final String nameSpace="kr.co.dong.boardMapper";


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

	@Override
	public BoardDTO getBoard(int bno) {
		return sqlSession.selectOne(nameSpace+".getBoard", bno);
	}

	@Override
	public int registerBoard(BoardDTO boardDTO) {
		return sqlSession.insert(nameSpace+".registerBoard", boardDTO);
	}

	@Override
	public int modifyBoard(BoardDTO boardDTO) {
		return sqlSession.update(nameSpace+".modifyBoard", boardDTO);
	}

	@Override
	public int deleteBoard(int bno) {
		return sqlSession.delete(nameSpace+".deleteBoard", bno);
	}

	@Override
	public int updateReadcnt(int bno) {
		return sqlSession.update(nameSpace+".readcount", bno);
	}

}

 

BoardService.java/BoardServiceImpl.java


BoardDAO에서 리턴된 result를 controller로 보낸다.

 

BoardService.java

package kr.co.dong.board;

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

public interface BoardService {
	
	// 글 전체목록
	public List<BoardDTO> boardList();
	
	// 글 상세보기	
	public BoardDTO getBoard(int bno);
	
	// 글 추가하기
	public int registerBoard(BoardDTO boardDTO);
	
	// 글 수정하기
	public int modifyBoard(BoardDTO boardDTO);
	
	// 글 삭제하기
	public int deleteBoard(int bno);

}

 

 

BoardServiceImpl.java

package kr.co.dong.board;

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

import javax.inject.Inject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service //서비스 레이어, 내부에서 자바 로직을 처리함
public class BoardServiceImpl implements BoardService {
	
	@Inject //주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입한다.
	private BoardDAO boardDAO;

	@Override
	public List<BoardDTO> boardList() {
		return boardDAO.boardList();
	}

	@Transactional(isolation = Isolation.READ_COMMITTED)	
	@Override
	public BoardDTO getBoard(int bno) {
		boardDAO.updateReadcnt(bno); // 글 상세보기 시 조회수 증가
		return boardDAO.getBoard(bno);
	}

	@Override
	public int registerBoard(BoardDTO boardDTO) {
		return boardDAO.registerBoard(boardDTO);
	}

	@Override
	public int modifyBoard(BoardDTO boardDTO) {
		return boardDAO.modifyBoard(boardDTO);
	}

	@Override
	public int deleteBoard(int bno) {
		return boardDAO.deleteBoard(bno);
	}

}

 

 

BoardController.java


 

BoardController.java

package kr.co.dong.board;

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

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 org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller // 웹 요청과 응답을 처리함
public class BoardController {
	
	private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
	
	@Inject // 주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입한다.
	private BoardService boardService;
	
	
	@RequestMapping(value="board/list")
	public ModelAndView list (HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		logger.info("글 전체목록");
		
		List<BoardDTO> list=boardService.boardList();
		
		ModelAndView mav = new ModelAndView ();
		mav.addObject("list", list);
		mav.setViewName("list");
		return mav;
		
	}
	
	@RequestMapping(value="board/detail",method=RequestMethod.GET)
	public ModelAndView datail(@RequestParam("bno") int bno, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		logger.info("글 상세보기");
		
		BoardDTO board= boardService.getBoard(bno);
		
		ModelAndView mav = new ModelAndView();
		List<BoardReplyDTO> list = boardService.replyList(bno);
		
		mav.addObject("list",list);
		mav.addObject("board",board);
		mav.setViewName("detail");
		return mav;
	}
	
	@RequestMapping(value="board/register", method=RequestMethod.GET)
	public String registerMove( HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
		logger.info("글 등록하기 View로 이동");
		return "register";
	}
	
	@RequestMapping(value="board/register", method=RequestMethod.POST)
	public String register(BoardDTO board, HttpServletRequest request, HttpSession session) throws Exception {
		logger.info("글 등록하기");

		int result=boardService.registerBoard(board);
		
		if (result==0) {
			logger.info("글 등록실패");
			return "redirect:register";
		}
		return "redirect:list";
	}
	
	@RequestMapping(value="board/update", method=RequestMethod.GET)
	public String modifyMove(@RequestParam("bno") int bno, Model model) throws Exception{ 
		logger.info("글 수정하기 View로 이동");
		
		BoardDTO board= boardService.getBoard(bno);
		
		model.addAttribute("board", board);
		return "update";
	}
	
	@RequestMapping(value="board/update", method=RequestMethod.POST)
	public String modify(BoardDTO board, HttpServletRequest request) throws Exception {
		
		logger.info("글 수정하기");
		int result=boardService.modifyBoard(board);
		
		if (result==0) {
			logger.info("글 수정실패");
			return "redirect:update";
		} else {
			logger.info("글 수정성공");
			return "redirect:list";
		}
	}
	
	@RequestMapping(value="board/delete", method=RequestMethod.GET)
	public String delete(@RequestParam("bno") int bno, HttpServletRequest request) throws Exception {
		logger.info("글 삭제하기");
		
		int result=boardService.deleteBoard(bno);
		
		if (result==0) {
			logger.info("글 삭제실패");
			return "redirect:detail?bno="+ bno;
		} else {
			logger.info("글 삭제성공");
			return "redirect:list";
		}
	}

}

 

 

BoardView


 

❶ 글 전체조회

 

❷ 글 상세조회

 

❸ 글 수정하기

 

글 수정하기 화면
수정 성공 후 게시판 목록으로 이동

❹ 글 삭제하기- 7번 글 삭제

 

7번 글 삭제 전 게시글 목록
7번 글 삭제성공 후 게시글 목록