Certification/Spring(2V0-72.22, SCP)

Spring MVC - 게시판 만들기CR(U)D - feat.입문편

엘호리스 2018. 8. 21. 02:22

이제 게시글 수정 기능을 구현을 해보자.

게시글 수정도 어려울 것 없다.

전 포스팅에서 현재까지 만들어진 게시판은 비밀번호를 입력하는 부분도 없어

비밀번호를 입력해야 하는 수정기능도 아니기 때문에 순수한 '수정' 기능에만 초점을 맞추겠다.


우선 수정 페이지를 구현해보자.


board_update.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%@ include file="../include/menu.jsp" %>
    <h2>board_read 페이지입니다.</h2>
    <a href="${path}/board/writer_page">글쓰기</a>
    <form name="updateform" method="POST" action="${path}/board/update.do">
        <div>글번호</div>
        <div><input name="bno" value="${data.bno}" type="text" readonly="readonly"/></div>
        <div>작성자</div>
        <div><input name="writer" value="${data.writer}" type="text" readonly="readonly"/></div>
        <div>게시글제목 : </div>
        <div><input name="title" value="${data.title}" type="text"/></div>
        <div>게시글내용 : </div>
        <div><textarea name="content" rows="5" cols="50">${data.content}</textarea></div>
        <div>조회수</div>
        <div><input name="viewcnt" value="${data.viewcnt}" type="text" readonly="readonly"/></div>
        <div>작성일자</div>
        <div><fmt:formatDate value="${data.regdate}" pattern="yyyy-MM-dd HH:mm:ss" /></div>
        <div>
            <input type="submit" value="글수정"/>
            <input type="reset" value="리셋"/>
        </div>
    </form>
    
</body>
</html>
cs



BoardController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.board.example.controller;
 
import java.util.List;
 
import javax.inject.Inject;
 
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 com.board.example.dto.BoardDTO;
import com.board.example.service.BoardService;
import com.sun.media.jfxmedia.logging.Logger;
 
 
@Controller
@RequestMapping("/board/*")
public class BoardController {
    @Inject
    BoardService boardService;
    
    // 과거 ModelAndView를 활용한 방법
//    @RequestMapping("list.do")
//    public ModelAndView boardMenu() throws Exception {
//        List<BoardDTO> list = boardService.boardList();
//        ModelAndView mav = new ModelAndView();
//        mav.setViewName("board/board_list");
//        mav.addObject("list", list);
//        return mav; // board/board_list.jsp로 이동
//    }
    
    // 현재 자주 쓰는 Model 클래스를 DI 하는 방법
    @RequestMapping("list.do")
    public String boardList(Model model) throws Exception {
        List<BoardDTO> list = boardService.boardList(); // list 변수에 결과 값을 담는다
        model.addAttribute("list", list); // model에 데이터 값을 담는다
        return "board/board_list"// board/board_list.jsp로 이동
    }
    
    // writer_page.jsp 매핑
    @RequestMapping("writer_page")
    public String writerpage() {
        return "board/writer_page";
    }
    
    // 게시글 from 데이터 처리
    @RequestMapping(value="insert.do", method=RequestMethod.POST)
    public String boardWriter(BoardDTO bdto) throws Exception {
        boardService.writerBoard(bdto);
        return "redirect:list.do";
    }
    
    // 게시글 상세내용 불러오기 
    @RequestMapping(value="read.do", method=RequestMethod.GET)
    public String boardRead(@RequestParam int bno,Model model) throws Exception {
        BoardDTO data = boardService.boardRead(bno); // bno값을 넘김
        model.addAttribute("data", data); // model에 데이터 값을 담는다
        return "board/board_read"// board/board_list.jsp로 이동
    }
    
    // 게시글 수정 페이지로 이동 
    @RequestMapping(value="updatepage", method=RequestMethod.GET)
    public String boardUpdate(@RequestParam int bno,Model model) throws Exception {
        BoardDTO data = boardService.boardRead(bno); // bno값을 넘김
        model.addAttribute("data", data); // model에 데이터 값을 담는다
        return "board/board_update"// board/board_update.jsp로 이동
    }
    
    // 게시글 수정 실행
    @RequestMapping(value="update.do", method=RequestMethod.POST)
    public String boardUpdatedo(BoardDTO bdto) throws Exception {
        boardService.updateBoard(bdto);
        return "redirect:list.do"// 리스트로 리다이렉트
    }
    
}
cs



BoardService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.board.example.service;
 
import java.util.List;
 
import com.board.example.dto.BoardDTO;
 
public interface BoardService {
    // 게시물 목록 조회
    public List<BoardDTO> boardList() throws Exception;
    // 게시물 글 쓰기
    public void writerBoard(BoardDTO bdto) throws Exception;
    // 게시물 상세내용 불러오기
    public BoardDTO boardRead(int bno) throws Exception;
    // 게시물 수정 실행
    public void updateBoard(BoardDTO bdto) throws Exception;
}
cs



BoardServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.board.example.service;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
 
import com.board.example.dao.BoardDAO;
import com.board.example.dto.BoardDTO;
 
@Service
public class BoardServiceImpl implements BoardService {
    @Inject
    BoardDAO boardDao;
    // 게시물 목록 불러오기
    @Override
    public List<BoardDTO> boardList() throws Exception {
        return boardDao.boardList(); 
    }
    // 게시물 글 쓰기
    @Override
    public void writerBoard(BoardDTO bdto) throws Exception {
        boardDao.writerBoard(bdto);
    }
    // 게시물 상세내용 불러오기
    @Override
    public BoardDTO boardRead(int bno) throws Exception {
        return boardDao.boardRead(bno);
    }
    // 게시물 수정
    @Override
    public void updateBoard(BoardDTO bdto) throws Exception {
        boardDao.boardUpdate(bdto);
    }
}
cs



BoardDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.board.example.dao;
 
import java.util.List;
 
 
import com.board.example.dto.BoardDTO;
 
public interface BoardDAO {
    // 게시물 목록 보기
    public List<BoardDTO> boardList() throws Exception;
    // 게시물 작성
    public void writerBoard(BoardDTO bdto) throws Exception;
    // 게시물 상세내용 불러오기
    public BoardDTO boardRead(int bno) throws Exception;
    // 게시물 수정
    public void boardUpdate(BoardDTO bdto) throws Exception;
}
cs



BoardDAOImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.board.example.dao;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
 
import com.board.example.dto.BoardDTO;
 
@Repository
public class BoardDAOImpl implements BoardDAO {
    @Inject
    SqlSession sqlSession;
    // 게시물 목록 불러오기
    @Override
    public List<BoardDTO> boardList() throws Exception {
        return sqlSession.selectList("board.boardList"); 
    }
    // 게시물 글쓰기
    @Override
    public void writerBoard(BoardDTO bdto) throws Exception {
        sqlSession.insert("board.boardWriter", bdto);
    }
    // 게시물 상세내용 불러오기
    @Override
    public BoardDTO boardRead(int bno) throws Exception {
        return sqlSession.selectOne("board.boardRead", bno);
    }
    @Override
    public void boardUpdate(BoardDTO bdto) throws Exception {
        sqlSession.update("board.boardUpdate", bdto);
    }
}
cs



boardMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?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와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
    <!-- 게시글 목록 불러오기 -->
    <select id="boardList" resultType="com.board.example.dto.BoardDTO">
        select bno,title,writer,regdate,viewcnt
        from board order by bno desc
    </select>
    <!-- Create 부분에 해당하는 글 쓰기 쿼리 -->
    <insert id="boardWriter">
        insert into board (bno, title, content, writer ) 
        values ((select nvl(max(bno)+1,1) from board), #{title}, #{content}, #{writer} )
    </insert>
    <!--  게시글 상세내용 불러오기  -->
    <select id="boardRead" resultType="com.board.example.dto.BoardDTO">
        select bno,title,content,writer,regdate,viewcnt
        from board where bno = #{bno}
    </select>
    <!--  게시글 수정하기  -->
    <update id="boardUpdate">
        update board set title=#{title},content=#{content} 
        where bno=#{bno}
    </update>
</mapper>
cs





급하게 그냥 구현에만 신경 쓰다 보니깐 굉장히 불합리적인 코드가 나왔다.

read 페이지 -> 글수정 페이지로 넘어가는 부분인데 이 과정에서 DB에 쿼리 질의를 한번 더 날리게 된다.

사실 read 페이지에서 이미 게시글에 대한 정보를 클라이언트에서 가지고 있기 때문에

javascript를 이용해 read 페이지에서 처리해도 충분할 것으로 보여진다.