2023.03.27 JSP
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="답글쓰기 완료">
<input type="reset" value="취소">
<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"> <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"> <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="글수정" />
<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="글삭제" />
<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 후기
페이징 쿼리 작성은 이제 쉬운데 이것을 불러올때 페이징 하는 방법이 약간 어려움이 있다.
잘 생각해봐야할 것 같다.