JSP 쇼핑몰 만들기

47. BoardReWriteForm 답글쓰기

답글쓰기 하려면 답글쓰기 폼 -> 답글쓰기 처리 proc - 답글저장dao ->게시글보기
순서대로 간다.
답글의 레벨을 처리하는 것이 가장 중요하고 어렵다.

re_step 과 re_level을 1씩 늘려주면된다.
부모들은 1씩 증가 나는 1로 들어가기

제목에는 value에 [답변]을 미리 넣어놔서 편하게 해놓자.

첫글은 ref restetp relevel은 필요가 없었다.
이글에는 이 값들을 받아왔으니 넘겨야한다.
input type="hidden"을 이용해서 form에서 사용자로부터 입력받지 않고 데이터를 넘기자.

<div align="center">
    <h2>답변글 입력하기</h2>
    <%
        //게시글 읽기에서 답변글쓰기를 클릭하면 넘겨주는 데이터들을 받아줌
        //넘어온 get요청 int값으로 변환
        int num = Integer.parseInt(request.getParameter("num"));
        int ref = Integer.parseInt(request.getParameter("ref"));
        int re_step = Integer.parseInt(request.getParameter("re_step"));
        int re_level = Integer.parseInt(request.getParameter("re_level"));
    %>
    <form action="BoardReWriteProc.jsp" method="post">
        <table border="1">
            <tr height="40">
                <td align="center" width="150px">작성자</td>
                <td width="450px"><input type="text" name="writer" size="60" /></td>
            </tr>

            <tr height="40">
                <td align="center" width="150px">제목</td>
                <td width="450px"><input type="text" name="subject" value="[답변]" size="60" /></td>
            </tr>

            <tr height="40">
                <td align="center" width="150px">이메일</td>
                <td width="450px"><input type="email" name="email" size="60" /></td>
            </tr>

            <tr height="40">
                <td align="center" width="150px">비밀번호</td>
                <td width="450px"><input type="password" name="password" size="60" /></td>
            </tr>

            <tr height="40">
                <td align="center" width="150px">글내용</td>
                <td width="450px"><textarea rows="10" cols="50" name="content"></textarea></td>
            </tr>

            <!-- form에서 사용자로부터 입력받지 않고 데이터를 넘김 -->
            <tr height="40">
                <td align="center" colspan="2">
                    <input type="hidden" name="ref" value="<%=ref%>"/>
                    <input type="hidden" name="re_step" value="<%=re_step%>"/>
                    <input type="hidden" name="re_level" value="<%=re_level%>"/>
                    <input type="submit" value="답글쓰기 완료"> &nbsp;&nbsp; 
                    <input type="reset" value="취소"> &nbsp;&nbsp;
                    <input type="button" value="전체 글 보기"  onclick="location.href='BoardList.jsp'" />
                </td>
            </tr>
        </table>
    </form>
</div>

48. BoardReWriteProc, BoardDAO

폼데이터를 처리해보자.
BoardWrite와 비슷한 처리를 한다.
답변글을 쓰려면 글을 그룹으로 만들고 re_step re_level을 먼저 수정해줘야한다.

부모 글보다 큰것들을 먼저 level들을 높여줘야한다. 나는 부모글보다 level +1해준다.

답글이기에 부모글의 re_step에 1을 더해준다.
re_level은 부모글보다 큰것들은 +1해줫으니 부모글에 +1해주면 본인의 레벨이 된다.

<%
    request.setCharacterEncoding("UTF-8");
%>
<!-- 데이터를 한번에 받아오는 빈클래스 사용 -->
<jsp:useBean id="boardBean" class="model.BoardBean">
    <jsp:setProperty name ="boardBean" property="*"/>
</jsp:useBean>

<%
    //데이터 베이스 객체 생성
    BoardDAO bdao = new BoardDAO();
    bdao.reWriteBoard(boardBean);

    //답변 데이터를 모두 저장 후 전체 게시글 보기를 설정
    response.sendRedirect("BoardList.jsp");
%>

// 답변글이 저장되는 메소드
public void reWriteBoard(BoardBean bean) {
    // 부모 글 그룹과 글레벨 글 스탭을 읽어들임
    int ref = bean.getRef();
    int re_step = bean.getRe_step();
    int re_level = bean.getRe_level();

    getCon();

    try {
        /////// 핵심코드////////
        // 부모 글보다 큰 re_level 의 값을 전부 1씩 증가
        String levelsql = "UPDATE BOARD SET RE_LEVEL = RE_LEVEL+1 WHERE REF=? AND RE_LEVEL > ?";

        pstmt = con.prepareStatement(levelsql);
        pstmt.setInt(1, ref); // 부모 1
        pstmt.setInt(2, re_level); // 부모 1보다 큰거
        pstmt.executeUpdate();

        // 답변글 데이터를 저장
        String sql = "INSERT INTO BOARD(WRITER, EMAIL, SUBJECT, PASSWORD, REG_DATE, REF, RE_STEP, RE_LEVEL, READCOUNT, CONTENT)"
                + " VALUES(?, ?, ?, ?, NOW(), ?, ?, ?, 0, ?)";

        pstmt = con.prepareStatement(sql);
        pstmt.setString(1, bean.getWriter());
        pstmt.setString(2, bean.getEmail());
        pstmt.setString(3, bean.getSubject());
        pstmt.setString(4, bean.getPassword());
        pstmt.setInt(5, ref);
        pstmt.setInt(6, re_step + 1);
        pstmt.setInt(7, re_level + 1);
        pstmt.setString(8, bean.getContent());
        pstmt.executeUpdate();

        con.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

49. 게시판 글수정

제목, 글내용 수정할 수 있도록 해보자.
그런데 글 수정을 누르면 누구글을 수정할지 알아야한다.
글 수정 업데이트 폼으로 해당 pk를 얻어오기
num을 기준으로 하기
기존 패스워드와 일치해서 글 수정할 수 있게 해주자.

<div align="center">
    <h2>게시글 수정</h2>
    <%
        //해당 게시글 번호를 통해 수정
        int num = Integer.parseInt(request.getParameter("num").trim());
        //하나의 게시글에 대한 정보를 리턴
        BoardDAO bdao = new BoardDAO();
        BoardBean bean = bdao.getOneUpdateBoard(num);
    %>
    <form action="BoardUpdateProc.jsp" method="post">
        <table border="1">
            <tr height="40">
                <td align="center" width="120px"> 작성자 </td>
                <td align="center" width="180px"> <%=bean.getWriter() %> </td>
                <td align="center" width="120px"> 작성일 </td>
                <td align="center" width="180px"> <%=bean.getReg_date() %> </td>
            </tr>

            <tr height="40">
                <td align="center" width="120px"> 제목 </td>
                <td width="480px" colspan="3"> &nbsp; <input type="text" name="subject" size="60" value=" <%=bean.getSubject() %> "/> </td>
            </tr>

            <tr height="40">
                <td align="center" width="120px"> 패스워드 </td>
                <td width="480px" colspan="3"> &nbsp; <input type="password" name="password" size="60"/> </td>
            </tr>

            <tr height="40">
                <td align="center" width="120px"> 글내용 </td>
                <td width="480px" colspan="3"> <textarea rows="10" cols="60" name="content" align="left"/><%= bean.getContent() %></textarea></td>
            </tr>

            <tr height="40">
                <td align="center" colspan="4">
                    <input type="hidden" name="num" value="<%= bean.getNum()%>"/>
                    <input type="submit" value="글수정" /> &nbsp;&nbsp;
                    <input type="button" value="전체글보기" onclick="location.href='BoardList.jsp'"/>
                </td>
            </tr>
        </table>
    </form>
</div>

50. 게시판 글수정-2

폼데이터를 읽어와서 글수정 처리하기
제목 패스워드 글내용 만 알아오면된다.

50.1 패스워드 얻는 메소드

// upsate와 delete시 필요한 패스워드 값을 리턴해주는 메소드
public String getPass(int num) {
    String pass = "";

    getCon();
    try {
        String sql = "SELECT PASSWORD FROM BOARD WHERE NUM = ?";
        pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, num);
        rs = pstmt.executeQuery();
        if (rs.next()) {
            pass = rs.getString(1);
        }
        con.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return pass;
}

50.2 글수정

useBean이 편한지 뭐가 편한지는 경험을 쌓아서 판별해야한다.

public void updateBoard(BoardBean bean) {
    getCon();

    try {
        String sql = "UPDATE BOARD SET SUBJECT=?, CONTENT=? WHERE NUM = ?";
        pstmt = con.prepareStatement(sql);
        pstmt.setString(1, bean.getSubject());
        pstmt.setString(2, bean.getContent());
        pstmt.setInt(3, bean.getNum());

        pstmt.executeUpdate();
        con.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

<%
    request.setCharacterEncoding("UTF-8");
%>
<!-- 사용자 데이터를 읽어들이는 빈클래스 설정 -->
<jsp:useBean id="boardBean" class="model.BoardBean">
    <jsp:setProperty name="boardBean" property="*"/>
</jsp:useBean>

<%
    //데이터베이스 연결
    BoardDAO bdao = new BoardDAO();
    //해당게시글의 패스워드 값을 얻어옴
    String pass = bdao.getPass(boardBean.getNum());

    //기존패스워드 값과 update시 작성햇던 pass값 같은지 비교
    if (pass.equals(boardBean.getPassword())){
        //데이터 수정 메소드호출
        bdao.updateBoard(boardBean);
        response.sendRedirect("BoardList.jsp");
    } else {
        //패스워드 틀리면 돌아가기
%>
<script type="text/javascript">
    alert("패스워드가 일치하지 않습니다 다시 확인후 수정해주세요");
    history.go(-1);
</script>
<%
    }
%>

51. 게시판 글삭제

글삭제 폼(DELETE)-> 글삭제 처리(DELETEPROC) -> 글삭제(DAO) -> 게시글보기

51.1 글삭제 폼

<%
    //해당 게시글 번호를 통해 수정
    int num = Integer.parseInt(request.getParameter("num").trim());
    //하나의 게시글에 대한 정보를 리턴
    BoardDAO bdao = new BoardDAO();
    BoardBean bean = bdao.getOneUpdateBoard(num);
%>
<div align="center">
    <h2>게시글 수정</h2>

    <form action="BoardDeleteProc.jsp" method="post">
        <table border="1">
            <tr height="40">
                <td width="120px" align="center">작성자</td>
                <td width="180px" align="center"><%= bean.getWriter() %></td>
                <td align="center" width="120px"> 작성일 </td>
                <td align="center" width="180px"> <%=bean.getReg_date() %> </td>
            </tr>

            <tr height="40">
                <td width="120px" align="center">제목</td>
                <td colspan="3" align="left"><%= bean.getSubject() %></td>
            </tr>

            <tr height="40">
                <td width="120px" align="center">비밀번호</td>
                <td colspan="3" align="left"><input type="password" name="password" szie="60" /></td>
            </tr>

            <tr height="40">
                <td colspan="4" align="center">
                    <input type="hidden" name="num" value="<%= bean.getNum() %>" />
                    <input type="submit" value="글삭제" /> &nbsp;&nbsp;
                    <input type="button" onclick="location.href='BoardList.jsp'" value="목록보기"/>
                </td>    
            </tr>
        </table>
    </form>
</div>

51.2 DELETEPROC

<%
    String pass = request.getParameter("password");
    int num = Integer.parseInt(request.getParameter("num").trim());

    //데이터베이스 연결
    BoardDAO bdao = new BoardDAO();
    String password = bdao.getPass(num);

    //기존 패스워드와 db패스워드비교
    if (password.equals(pass)){
        //같다면 지우기
        bdao.deleteBoard(num);
        response.sendRedirect("BoardList.jsp");
    } else {
%>    
    <script type="text/javascript">
        alert("패스워드가 틀려서 삭제할 수 없습니다. 패스워드를 확인해주세요");
        history.go(-1);
    </script>
<%
    }
%>

51.3 BoardDAO

// 하나의 게시글 삭제
public void deleteBoard(int num) {
    getCon();

    try {
        String sql = "DELETE FROM BOARD WHERE NUM = ?";
        pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, num);
        pstmt.executeUpdate();
        con.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

52. 전체 글보기 (카운터)

전체글 보기에서 카운터 (데이터를 카운팅해서 )페이징 하는 것이다.
가정을 하면서 소스코드를 작성하고 상상만하자.
글쓰기를 맨윗단 오른쪽에 할 것임.
글쓰기 자리에 이전 12345 다음

한화면에 10개씩만 보여주고 싶다.
카운터링을 하면된다.

오라클은 between ? and?로 조절을 해줘야하는데 mysql은 limit써야한다.
1.화면에 보여질 게시글의 개수를 지정
2.현재 카운터를 클릭한 번호값을 읽어오기해야한다.
3.만약 처음 boardList.jsp를 클릭하거나 수정삭제등 하고 왓을때 값이 없기에 null처리해줘야한다.

52.1 필요한 변수선언

<%
    //화면에 보여질 게시글의 개수를 지정
    int pageSize = 10;
    //현재 카운터를 클릭한 번호값을 읽어오기
    String pageNum = request.getParameter("pageNum");
    //만약 처음 boardList.jsp를 클릭하거나 수정삭제등 하고 왓을때 값이 없기에 null처리해주기
    if (pageNum ==null){
        pageNum = "1";
    }
    int count = 0; //전체글의 개수를 저장하는 변수
    int number = 0; //페이지 넘버링변수

    //현재 보고자하는 페이지 숫자를 저장
    int currentPage = Integer.parseInt(pageNum);

    //전체 게시글 내용 jsp로 가져오기
    BoardDAO bdao = new BoardDAO();

    //전체 게시글의 개수 읽어오는 메소드 호출
    count = bdao.getAllCount();

    //현재 페이지에 보여줄 시작 번호를 설정 =db에서 불러올 시작번호
    int startRow = (currentPage -1) * pageSize + 1;
    //int endRow = currentPage * pageSize;
    int endRow = pageSize;

    //전체 게시글을 리턴 받아주는 소스
    List<BoardBean> list = bdao.getAllBoard(startRow, endRow); 

    //테이블에 표시할 번호를 지정
    number = count - (currentPage - 1) * pageSize;
%>

52.2 게시글 총 개수 얻기

게시글의 총개수를 얻어와야 페이징이 가능하다.

public int getAllCount() {
    getCon();
    int count = 0;
    try {
        String sql = "SELECT COUNT(NUM) COUNT FROM BOARD";
        pstmt = con.prepareStatement(sql);
        rs = pstmt.executeQuery();
        if (rs.next()) {
            count = rs.getInt(1);
        }

        con.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return count;
}

53. 전체 글보기 (카운터)

현재 페이지에 보여줄 시작 번호를 설정 =db에서 불러올 시작번호
int startRow = (currentPage -1) * pageSize + 1; // 1 11 21 31 -> 등차수열임
int endRow = currentPage * pageSize; 10 / 20/ 30인데 mysql은 그냥 pageSize만 를 넣어주면된다.

53.1 getAllBoard()

getAllBoard를 설정해주면된다.
오라클은 rownum을 기준으로 복잡하게 쿼리를 짜야한다.
0~10이런식으로 나오게 start - 1과 end(pageSize)값을 넣어주자.

public List<BoardBean> getAllBoard(int start, int end) {
    // 리턴할 객체 선언
    List<BoardBean> list = Collections.synchronizedList(new ArrayList<>());

    getCon();

    try {
        String sql = "SELECT * FROM BOARD ORDER BY REF DESC, RE_STEP ASC limit ?, ?";

        pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, start - 1);
        pstmt.setInt(2, end);
        rs = pstmt.executeQuery();
}

53.2 페이지 카운터링 소스 작성

<p>
<!-- 페이지 카운터링 소스를 작성 -->
<% 
    if(count > 0){
        int pageCount = count / pageSize + (count%pageSize == 0 ? 0 : 1); //카운터링숫자를 얾나까지 보여줄건지를 결정
        //시작페이지 숫자를 설정
        int startPage = 1;

        if (currentPage % 10 != 0){
            startPage = (int) (currentPage / 10) * 10 + 1;
        }  else{
            startPage = ((int) (currentPage / 10) -1 ) * 10 + 1;
        }

        int pageBlock = 10; //카운터링 처리 숫자
        int endPage = startPage + pageBlock -1 ; //화면에 보여질 페이지의 마지막 숫자

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

        //이전 이라는 링크를 만들껀지 파악
        if (startPage > 10){
%>        
    <a href="BoardList.jsp?pageNum=<%= startPage - 10%>">[이전]</a>
<% 
        }
        //페이징 처리
        for(int i = startPage; i <= endPage; i++){
%>    

    <a href="BoardList.jsp?pageNum=<%= i %>">[<%=i %>]</a>
<%    
        }
        //다음이라는 링크를 만들건지 파악
        if (endPage < pageCount){
%>        
    <a href="BoardList.jsp?pageNum=<%= startPage+10 %>">[다음]</a>        
<%            
        }
    }
%>
</p>

2023.03.27 후기

페이징 쿼리 작성은 이제 쉬운데 이것을 불러올때 페이징 하는 방법이 약간 어려움이 있다.
잘 생각해봐야할 것 같다.

'기초단계 > JSP&Servlet' 카테고리의 다른 글

2023.03.29 JSP  (0) 2023.03.29
2023.03.28 JSP  (0) 2023.03.29
2023.03.26 JSP  (0) 2023.03.26
2023.03.25 JSP  (0) 2023.03.26
2023.03.23 JSP  (0) 2023.03.23

+ Recent posts