다가오는 다음을 향해
[Spring MVC] 댓글 구현(게시판 구현 후 ) 본문
[ 개발환경 ]
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
- table 설계
- BoardReplyDTO 작성
- boardMapper.xml
- BoardDAO.java / BoardDAOImpl.java
- BoardService.java /BoardServiceImpl.java
- BoardController.java
테이블 설계
Table: board_reply | |
댓글 번호 | bno int(11) PK AI |
댓글 작성자 | content varchar(45) not null |
댓글 내용 | id varchar(45) not null |
댓글 작성일 | regdate datetime |
게시판 번호 | readcnt int(11) |
BoardReplyDTO
BoardReplyDTO.java
package kr.co.dong.board;
public class BoardReplyDTO {
private int reno; // 댓글번호
private String rewriter; // 댓글작성자
private String rememo; // 댓글내용
private String redate; // 댓글작성일
private int bno; // 게시판번호
public int getReno() {
return reno;
}
public void setReno(int reno) {
this.reno = reno;
}
public String getRewriter() {
return rewriter;
}
public void setRewriter(String rewriter) {
this.rewriter = rewriter;
}
public String getRememo() {
return rememo;
}
public void setRememo(String rememo) {
this.rememo = rememo;
}
public String getRedate() {
return redate;
}
public void setRedate(String redate) {
this.redate = redate;
}
public int getBno() {
return bno;
}
public void setBno(int bno) {
this.bno = bno;
}
}
boardMapper.xml
boardMapper를 작성하기 전
mybatis-config.xml에 BoardReply Type의 별칭을 설정한다.
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"/>
<typeAlias alias="reply" type="kr.co.dong.board.BoardReplyDTO"/>
</typeAliases>
</configuration>
Mybatis의 SqlSession을 호출하는 XML 매핑구문을 작성한다. (SqlSessionFactory)
boardMapper.xml | |
게시글 번호에 해당하는 댓글 전체목록 |
<select id="replyList" parameterType="java.lang.Integer" resultType="reply"> select * from board_reply where bno=#{bno} </select> |
댓글 상세보기 | <select id="getReply" parameterType="java.lang.Integer" resultType="reply"> select * from board_reply where reno=#{reno} </select> |
댓글 등록하기 | <insert id="registerReply" parameterType="reply"> insert into board_reply (reno, rewriter, rememo, redate, bno) values (#{reno}, #{rewriter}, #{rememo}, now(), #{bno}) </insert> |
댓글 수정하기 | <update id="modifyReply" parameterType="reply"> update board_reply <set> <if test="rewriter != null">rewriter=#{rewriter},</if> <if test="rememo !=null">rememo=#{rememo}</if> </set> where reno=#{reno} </update> |
댓글 삭제하기 | <delete id="deleteReply" parameterType="java.lang.Integer"> delete from board_reply where reno=#{reno} </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>
<!--게시글번호에 해당하는 댓글 전체조회-->
<select id="replyList" parameterType="java.lang.Integer" resultType="reply">
select * from board_reply where bno=#{bno}
</select>
<!--댓글 상세조회-->
<select id="getReply" parameterType="java.lang.Integer" resultType="reply">
select * from board_reply where reno=#{reno}
</select>
<!--댓글 등록하기 -->
<insert id="registerReply" parameterType="reply">
insert into board_reply (reno, rewriter, rememo, redate, bno)
values (#{reno}, #{rewriter}, #{rememo}, now(), #{bno})
</insert>
<!--댓글 수정하기-->
<update id="modifyReply" parameterType="reply">
update board_reply
<set>
<if test="rewriter != null">rewriter=#{rewriter},</if>
<if test="rememo !=null">rememo=#{rememo}</if>
</set>
where reno=#{reno}
</update>
<!--댓글 삭제하기-->
<delete id="deleteReply" parameterType="java.lang.Integer">
delete from board_reply where reno=#{reno}
</delete>
</mapper>
BoardDAO.java/BoardDAOImpl.java
Mybatis로 작성한 SqlSessionFactory에서 인터페이스를 호출하기 때문에
boardDAO interface와 boardDAO를 implements한 boardDAOImpl 를 작성한다.
BoardDAO.java
package kr.co.dong.board;
import java.util.List;
import java.util.Map;
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);
// 글 번호의 댓글 전체목록
public List<BoardReplyDTO> replyList(int bno);
// 댓글 상세조회
public BoardReplyDTO getReply(int reno);
// 댓글 등록
public int registerReply(BoardReplyDTO reply);
// 댓글 수정
public int modifyReply(BoardReplyDTO reply);
// 댓글 삭제
public int deleteReply(int reno);
}
BoardDAOImpl.java
package kr.co.dong.board;
import java.util.List;
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);
}
@Override
public List<BoardReplyDTO> replyList(int bno) {
return sqlSession.selectList(nameSpace+".replyList", bno);
}
@Override
public BoardReplyDTO getReply(int reno) {
return sqlSession.selectOne(nameSpace + ".getReply", reno);
}
@Override
public int registerReply(BoardReplyDTO reply) {
return sqlSession.insert(nameSpace+".registerReply", reply);
}
@Override
public int modifyReply(BoardReplyDTO reply) {
return sqlSession.update(nameSpace+".modifyReply", reply);
}
@Override
public int deleteReply(int reno) {
return sqlSession.delete(nameSpace+".deleteReply", reno);
}
}
BoardService.java/BoardServiceImpl.java
BoardDAO에서 리턴된 result를 controller로 보낸다.
BoardService.java
package kr.co.dong.board;
import java.util.List;
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);
// 글 번호의 댓글 전체목록
public List<BoardReplyDTO> replyList(int bno);
// 댓글 상세조회
public BoardReplyDTO getReply(int reno);
// 댓글 등록하기
public int registerReply(BoardReplyDTO reply);
// 댓글 수정하기
public int modifyReply(BoardReplyDTO reply);
// 댓글 삭제하기
public int deleteReply(int reno);
}
BoardServiceImpl.java
package kr.co.dong.board;
import java.util.List;
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);
}
@Override
public List<BoardReplyDTO> replyList(int bno) {
return boardDAO.replyList(bno);
}
@Override
public BoardReplyDTO getReply(int reno) {
return boardDAO.getReply(reno);
}
@Override
public int registerReply(BoardReplyDTO reply) {
return boardDAO.registerReply(reply);
}
@Override
public int modifyReply(BoardReplyDTO reply) {
return boardDAO.modifyReply(reply);
}
@Override
public int deleteReply(int reno) {
return boardDAO.deleteReply(reno);
}
}
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/logout", method=RequestMethod.GET)
public String logout(HttpSession session) {
logger.info("로그아웃");
session.invalidate();
return "redirect:/";
}
@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";
}
}
@RequestMapping(value="board/reply", method=RequestMethod.GET)
public String reply(@RequestParam("bno") int bno, Model model) throws Exception {
logger.info("댓글등록 View로 이동");
model.addAttribute("bno",bno);
return "reply";
}
@RequestMapping(value="board/reply", method=RequestMethod.POST)
public String reply(BoardReplyDTO reply, HttpServletRequest request) throws Exception {
logger.info("댓글 등록하기");
int result = boardService.registerReply(reply);
if (result==0) {
logger.info("댓글등록 실패");
return "reply";
} else {
logger.info("댓글등록 성공");
return "redirect:detail?bno="+ reply.getBno();
}
}
@RequestMapping(value="board/replyupdate", method=RequestMethod.GET)
public String modifyReplyMove(@RequestParam("reno") int reno, Model model) throws Exception {
logger.info("댓글수정 View로 이동");
BoardReplyDTO reply = boardService.getReply(reno);
model.addAttribute("boardreply",reply);
return "replyupdate";
}
@RequestMapping(value="board/replyupdate", method=RequestMethod.POST)
public String modifyReply(BoardReplyDTO reply, RedirectAttributes rttr) throws Exception {
logger.info("댓글 수정하기");
int result = boardService.modifyReply(reply);
if (result==0) {
logger.info("댓글 수정실패");
return "redirect:reply?reno="+reply.getReno();
} else {
logger.info("댓글 수정성공" + reply.getBno());
return "redirect:detail?bno="+reply.getBno();
}
}
@RequestMapping(value="board/deleteReply", method=RequestMethod.GET)
public String deleteReply(@RequestParam("reno") int reno, HttpServletRequest request) throws Exception {
logger.info("댓글 삭제하기");
int result=boardService.deleteReply(reno);
if (result==0) {
logger.info("댓글 삭제실패");
return "redirect:detail?bno="+ reno;
} else {
logger.info("댓글 삭제성공");
return "redirect:list";
}
}
}
ReplyView
❶ 글번호에 해당하는 댓글 목록 조회
❷ 댓글 수정
❸ 댓글 삭제하기
'국비학원 공부노트 > Spring MVC' 카테고리의 다른 글
[Spring MVC] 게시글 자동등록 - 단위테스트 (0) | 2022.04.14 |
---|---|
[Spring MVC] 핸들러 인터셉터 (HandlerInterceptor)-로그인인증 (0) | 2022.04.14 |
[Spring MVC] 게시판 구현 (0) | 2022.04.13 |
[Spring MVC] DB 로그인, 로그아웃 구현 (0) | 2022.03.16 |
[Spring MVC] 기본동작 구현 (0) | 2022.03.15 |