본문 바로가기

Java 웹 개발

21.10.28 - 웹 개발 입문 54일차

홈페이지 - 댓글 구현

 

 

[ 댓글 등록 구현하기 ]

- SQL reply 테이블 만들기

create table reply(
reply_no number primary key,
board_no references board(board_no) on delete cascade,
reply_writer references member(member_id) on delete set null,
reply_content varchar2(1500) not null,
reply_time date default sysdate not null,
reply_superno number not null,
reply_groupno number not null,
reply_depth number not null
);
create sequence reply_seq;

 

- ReplyDto 만들기

package home.beans;

import java.sql.Date;
import java.text.Format;
import java.text.SimpleDateFormat;

public class ReplyDto {
	private int replyNo;
	private int boardNo;
	private String replyWriter;
	private String replyContent;
	private Date replyTime;
	private int replySuperno;
	private int replyGroupno;
	private int replyDepth;
	public ReplyDto() {
		super();
	}
	public int getReplyNo() {
		return replyNo;
	}
	public void setReplyNo(int replyNo) {
		this.replyNo = replyNo;
	}
	public int getBoardNo() {
		return boardNo;
	}
	public void setBoardNo(int boardNo) {
		this.boardNo = boardNo;
	}
	public String getReplyWriter() {
		return replyWriter;
	}
	public void setReplyWriter(String replyWriter) {
		this.replyWriter = replyWriter;
	}
	public String getReplyContent() {
		return replyContent;
	}
	public void setReplyContent(String replyContent) {
		this.replyContent = replyContent;
	}
	public Date getReplyTime() {
		return replyTime;
	}
	public void setReplyTime(Date replyTime) {
		this.replyTime = replyTime;
	}
	public int getReplySuperno() {
		return replySuperno;
	}
	public void setReplySuperno(int replySuperno) {
		this.replySuperno = replySuperno;
	}
	public int getReplyGroupno() {
		return replyGroupno;
	}
	public void setReplyGroupno(int replyGroupno) {
		this.replyGroupno = replyGroupno;
	}
	public int getReplyDepth() {
		return replyDepth;
	}
	public void setReplyDepth(int replyDepth) {
		this.replyDepth = replyDepth;
	}

   	 // 댓글 작성 시간 설정 (2000-10-10 00:00:00)
	public String getReplyFullTime() {
		Format f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return f.format(replyTime);
	}
	
}

 

- ReplyDao 특정 게시글에 대한 댓글 목록 조회 기능 만들기

package home.beans;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class ReplyDao {

	//특정 게시글에 대한 댓글 목록 조회 기능
	public List<ReplyDto> list(int boardNo) throws Exception {
		Connection con = JdbcUtils.connect2();

		String sql = "select * from reply where board_no = ? order by reply_no desc";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setInt(1, boardNo);
		ResultSet rs = ps.executeQuery();

		List<ReplyDto> list = new ArrayList<>();
		while(rs.next()) {
			ReplyDto replyDto = new ReplyDto();

			replyDto.setReplyNo(rs.getInt("reply_no"));
			replyDto.setBoardNo(rs.getInt("board_no"));
			replyDto.setReplyWriter(rs.getString("reply_writer"));
			replyDto.setReplyContent(rs.getString("reply_content"));
			replyDto.setReplyTime(rs.getDate("reply_time"));
			replyDto.setReplySuperno(rs.getInt("reply_superno"));
			replyDto.setReplyGroupno(rs.getInt("reply_groupno"));
			replyDto.setReplyDepth(rs.getInt("reply_depth"));

			list.add(replyDto);
		}

		con.close();

		return list;
	}

}

 

- ReplyDao 댓글 등록 기능 만들기

public void insert(ReplyDto replyDto) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "insert into reply values(reply_seq.nextval, ?, ?, ?, sysdate, 0, 0, 0)";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, replyDto.getBoardNo());
	ps.setString(2, replyDto.getReplyWriter());
	ps.setString(3, replyDto.getReplyContent());
	ps.execute();

	con.close();
}

 

- 댓글 등록 처리 (BoardReplyInsertServlet.java) 만들기

package home.servlet.board;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import home.beans.BoardDao;
import home.beans.ReplyDao;
import home.beans.ReplyDto;

@WebServlet(urlPatterns = "/board/reply/insert.txt")
public class BoardReplyInsertServlet extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//입력 : ReplyDto(파라미터 : boardNo + replyContent , 세션 : replyWriter)
			ReplyDto replyDto = new ReplyDto();
			replyDto.setBoardNo(Integer.parseInt(req.getParameter("boardNo")));
			replyDto.setReplyContent(req.getParameter("replyContent"));

			replyDto.setReplyWriter((String)req.getSession().getAttribute("ses"));

			//처리
			//1. 댓글 등록
			//2. 게시글의 댓글 수 조정
			ReplyDao replyDao = new ReplyDao();
			replyDao.insert(replyDto);

			BoardDao boardDao = new BoardDao();
			boolean success = boardDao.refreshReplyCount(replyDto.getBoardNo());

			//출력
			resp.sendRedirect("../detail.jsp?boardNo="+replyDto.getBoardNo());
			//resp.sendRedirect(req.getContextPath()+"/board/detail.jsp?boardNo="+replyDto.getBoardNo());
		}
		catch(Exception e) {
			e.printStackTrace();
			resp.sendError(500);
		}
	}
}

 

- ReplyDao 댓글 개수 갱신 기능 만들기

public boolean refreshReplyCount(int boardNo) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "update board "
			+ "set board_reply=(select count(*) from reply where board_no=?) "
			+ "where board_no=?";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, boardNo);
	ps.setInt(2, boardNo);
	int result = ps.executeUpdate();

	con.close();

	return result > 0;
}

 

- BoardDto에 댓글이 존재하는지 확인하는 메소드 추가하기

public boolean isReplyExist() {
	return this.boardReply > 0;
}

 

- 게시판 상세보기 (detail.jsp) 수정하기

<%@page import="home.beans.ReplyDto"%>
<%@page import="java.util.List"%>
<%@page import="home.beans.ReplyDao"%>
<%@page import="java.util.HashSet"%>
<%@page import="java.util.Set"%>
<%@page import="home.beans.BoardDto"%>
<%@page import="home.beans.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 입력 : 게시글번호(boardNo) --%>
<%
	int boardNo = Integer.parseInt(request.getParameter("boardNo"));
%>

<%-- 처리 --%>
<%
String memberId = (String)session.getAttribute("ses"); 
BoardDao boardDao = new BoardDao();

//1. boardViewedNo 라는 이름의 저장소를 세션에서 꺼내어 본다.
Set<Integer> boardViewedNo = (Set<Integer>)session.getAttribute("boardViewedNo");

//2. boardViewedNo 가 null 이면 "처음 글을 읽는 상태"임을 말하므로 저장소를 신규로 생성
if(boardViewedNo == null){
boardViewedNo = new HashSet<>();
}

//3. 현재 글 번호를 저장소에 추가해본다
//3-1. 추가가 된다면 이 글은 처음 읽는 글
//3-2. 추가가 안된다면 이 글은 두 번 이상 읽은 글
if (boardViewedNo.add(boardNo)) {//처음 읽은 글인 경우
boardDao.readUp(boardNo, memberId);//조회수 증가(남에 글일때만)
//System.out.println("이 글은 처음 읽는 글입니다");
} else {
//System.out.println("이 글은 읽은 적이 있습니다");
}

//System.out.println("저장소 : " + boardViewedNo);

//4. 저장소 갱신
session.setAttribute("boardViewedNo", boardViewedNo);

BoardDto boardDto = boardDao.get(boardNo);//단일조회

//본인 글인지 아닌지를 판정하는 변수
//boolean owner = 세션의ses 값과 게시글 작성자가 같은가?;

boolean owner = boardDto.getBoardWriter().equals(memberId);
%>

<%
	//현재 게시글에 대한 댓글을 조회
	ReplyDao replyDao = new ReplyDao();
	List<ReplyDto> replyList = replyDao.list(boardNo);
%>

<%-- 출력 --%>
<jsp:include page="/template/header.jsp"></jsp:include>

<h2><%=boardDto.getBoardNo()%>번 게시글</h2>

<table border="1" width="80%">
	<tbody>
		<tr>
			<td>
				<h3><%=boardDto.getBoardTitle()%></h3>
			</td>
		</tr>
		<tr>
			<td>
				등록일 : <%=boardDto.getBoardTime()%>
				|
				작성자 : <%=boardDto.getBoardWriter()%>
				|
				조회수 : <%=boardDto.getBoardRead()%>
			</td>
		</tr>
		<!-- 답답해 보이지 않도록 기본높이를 부여 -->
		<tr height="250" valign="top">
			<td>
				<pre><%=boardDto.getBoardContent()%></pre>
			</td>		
		</tr>
		<tr>
			<td align="right">
				<a href="write.jsp">글쓰기</a>
				<a href="list.jsp">목록보기</a>
				<%if(owner){ %>
				<a href="edit.jsp?boardNo=<%=boardDto.getBoardNo()%>">수정하기</a>
				<%-- 				<a href="delete.txt?boardNo=<%=boardNo%>">삭제하기</a> --%>
				<a href="delete.txt?boardNo=<%=boardDto.getBoardNo()%>">삭제하기</a>
				<%} %>
			</td>
		</tr>
	</tbody>
</table>

<%-- 댓글 작성, 목록 영역 --%>
<form action="./reply/insert.txt" method="post">
	<input type="hidden" name="boardNo" value="<%=boardDto.getBoardNo()%>">
	<table border="0" width="80%">
		<tbody>
			<tr>
				<td>
					<textarea name="replyContent" required rows="4" cols="80"></textarea>
				</td>
				<td>
					<input type="submit" value="댓글작성">
				</td>
			</tr>
		</tbody>
	</table>
</form>

<%if(replyList.isEmpty()){ %>
	<!-- 댓글이 없을 경우에 표시할 테이블 -->
	<table border="1" width="80%">
		<tbody>
			<tr><th>작성된 댓글이 없습니다</th></tr>
		</tbody>
	</table>
<%}else{ %>
	<!-- 댓글이 있을 경우에 표시할 테이블 -->
	<table border="1" width="80%">
		<tbody>
			<%for(ReplyDto replyDto : replyList){ %>
			<tr>
				<td width="30%">
					<%=replyDto.getReplyWriter()%>
					<br>
					(<%=replyDto.getReplyFullTime()%>)
				</td>
				<td>
					<pre><%=replyDto.getReplyContent()%></pre>
				</td>
				<td width="15%">수정 | 삭제</td>
			</tr>
			<%} %>
		</tbody>
	</table>
<%} %>

<jsp:include page="/template/footer.jsp"></jsp:include>

 

- 게시판 목록 (list.jsp) 수정하기

[ 수정 전 코드 ]

<table border="1" width="90%">
	<thead>
		<tr>
			<th>번호</th>
			<th width="45%">제목</th>
			<th>작성자</th>
			<th>작성일</th>
			<th>조회수</th>
		</tr>
	</thead>
	<tbody align="center">
		<%for(BoardDto boardDto : pagination.getList()){ %>
		<tr>
			<td><%=boardDto.getBoardNo()%></td>
			<td align="left"><a href="detail.jsp?boardNo=<%=boardDto.getBoardNo()%>"><%=boardDto.getBoardTitle()%></a></td>
			<td><%=boardDto.getBoardWriter()%></td>
			<td><%=boardDto.getBoardTime()%></td>
			<td><%=boardDto.getBoardRead()%></td>
		</tr>
		<%} %>
	</tbody>
</table>

 

[ 수정 후 코드 ]

<table border="1" width="90%">
	<thead>
		<tr>
			<th>번호</th>
			<th width="45%">제목</th>
			<th>작성자</th>
			<th>작성일</th>
			<th>조회수</th>
		</tr>
	</thead>
	<tbody align="center">
		<%for(BoardDto boardDto : pagination.getList()){ %>
		<tr>
			<td><%=boardDto.getBoardNo()%></td>
			<td align="left">
				<a href="detail.jsp?boardNo=<%=boardDto.getBoardNo()%>">
					<%=boardDto.getBoardTitle()%>
				</a>

				<!-- 제목 뒤에 댓글 개수를 출력한다 -->
				<%
				//if(boardDto.getBoardReply() > 0){
				if(boardDto.isReplyExist()){
				%>
					[<%=boardDto.getBoardReply()%>]
				<%} %>
			</td>
			<td><%=boardDto.getBoardWriter()%></td>
			<td><%=boardDto.getBoardTime()%></td>
			<td><%=boardDto.getBoardRead()%></td>
		</tr>
		<%} %>
	</tbody>
</table>

 

- 댓글 등록 구현 완료

 

- 댓글 갯수 구현 완료

 

 

 

[ 댓글 삭제 구현하기 ]

- 게시판 상세보기 (detail.jsp) 수정하기

[ 수정 전 코드 ]

	<!-- 댓글이 있을 경우에 표시할 테이블 -->
	<table border="1" width="80%">
		<tbody>
			<%for(ReplyDto replyDto : replyList){ %>
			<tr>
				<td width="30%">
					<%=replyDto.getReplyWriter()%>
					<br>
					(<%=replyDto.getReplyFullTime()%>)
				</td>
				<td>
					<pre><%=replyDto.getReplyContent()%></pre>
				</td>
				<td width="15%">수정 | 삭제</td>
			</tr>
			<%} %>
		</tbody>
	</table>
<%} %>

 

[ 수정 후 코드 ]

	<!-- 댓글이 있을 경우에 표시할 테이블 -->
	<table border="1" width="80%">
		<tbody>
			<%for(ReplyDto replyDto : replyList){ %>
			<%
				//본인 댓글인지 판정 : 세션의 회원아이디와 댓글의 작성자를 비교
				//작성자 댓글인지 판정 : 게시글 작성자와 댓글의 작성자를 비교
				boolean myReply = memberId.equals(replyDto.getReplyWriter());
				boolean ownerReply = boardDto.getBoardWriter().equals(replyDto.getReplyWriter());
			%>
			<tr>
				<td width="30%">
					<%=replyDto.getReplyWriter()%>
					<%-- 게시글 작성자의 댓글에는 표시 --%>
					<%if(ownerReply){ %>
						(작성자)
					<%} %>
					<br>
					(<%=replyDto.getReplyFullTime()%>)
				</td>
				<td>
					<pre><%=replyDto.getReplyContent()%></pre>
				</td>
				<td width="15%">
				<%-- 현재 사용자가 작성한 글에만 수정, 삭제를 표시 --%>
				<%if(myReply){ %>
				수정 | 
				<a href="reply/delete.txt?boardNo=<%=replyDto.getBoardNo()%>&replyNo=<%=replyDto.getReplyNo()%>">삭제</a>
				<%} %>
				</td>
			</tr>
			<%} %>
		</tbody>
	</table>
<%} %>

 

- ReplyDao 댓글 삭제 기능 만들기

public boolean delete(int replyNo) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "delete reply where reply_no = ?";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, replyNo);
	int result = ps.executeUpdate();

	con.close();

	return result > 0;
}

 

- 댓글 삭제 처리 (BoardReplyDeleteServlet.java) 만들기

댓글 삭제 및 게시글 댓글수 조정

package home.servlet.board;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import home.beans.BoardDao;
import home.beans.ReplyDao;

@WebServlet(urlPatterns = "/board/reply/delete.txt")
public class BoardReplyDeleteServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//입력 : 게시글번호(boardNo), 댓글번호(replyNo)
			int boardNo = Integer.parseInt(req.getParameter("boardNo"));
			int replyNo = Integer.parseInt(req.getParameter("replyNo"));

			//처리 : 댓글삭제, 게시글 댓글수 조정
			ReplyDao replyDao = new ReplyDao();
			boolean success = replyDao.delete(replyNo);

			BoardDao boardDao = new BoardDao();
			boolean success2 = boardDao.refreshReplyCount(boardNo);

			//출력 : 게시글로 redirect
			resp.sendRedirect("../detail.jsp?boardNo="+boardNo);
			//resp.sendRedirect(req.getContextPath()+"/board/detail.jsp?boardNo="+boardNo);
		}
		catch(Exception e) {
			e.printStackTrace();
			resp.sendError(500);
		}
	}
}

 

- 댓글 삭제 기능 구현 완료

 

 

 

[ 댓글 수정 구현하기 ]

- 게시판 상세보기 (detail.jsp) 수정하기

[ 수정 전 코드 ]

<tr>
	<td width="30%">
		<%=replyDto.getReplyWriter()%>
		<%-- 게시글 작성자의 댓글에는 표시 --%>
		<%if(ownerReply){ %>
			(작성자)
			<%} %>
		<br>
		(<%=replyDto.getReplyFullTime()%>)
	</td>
	<td>
		<pre><%=replyDto.getReplyContent()%></pre>
	</td>
	<td width="15%">
	<%-- 현재 사용자가 작성한 글에만 수정, 삭제를 표시 --%>
	<%if(myReply){ %>
	수정 | 
	<a href="reply/delete.txt?boardNo=<%=replyDto.getBoardNo()%>&replyNo=<%=replyDto.getReplyNo()%>">삭제</a>
	<%} %>
	</td>
</tr>

 

[ 수정 후 코드 ]

<tr class="view-row">
	<td width="30%">
		<%=replyDto.getReplyWriter()%>
		<%-- 게시글 작성자의 댓글에는 표시 --%>
		<%if(ownerReply){ %>
			(작성자)
		<%} %>
		<br>
		(<%=replyDto.getReplyFullTime()%>)
	</td>
	<td>
		<pre><%=replyDto.getReplyContent()%></pre>
	</td>
	<td width="15%">
		<%-- 현재 사용자가 작성한 글에만 수정, 삭제를 표시 --%>
		<%if(myReply){ %>
		<a class="edit-btn">수정</a> |
		<a href="reply/delete.txt?boardNo=<%=replyDto.getBoardNo()%>&replyNo=<%=replyDto.getReplyNo()%>">삭제</a>
		<%} %>
		</td>
</tr>
		<%-- 본인 글일 경우 수정을 위한 공간을 추가적으로 생성 --%>
		<%if(myReply){ %>
		<tr class="edit-row">
			<td colspan="3">
				<form action="reply/edit.txt" method="post">
					<input type="hidden" name="replyNo" value="<%=replyDto.getReplyNo()%>">
					<input type="hidden" name="boardNo" value="<%=replyDto.getBoardNo()%>">
					<textarea name="replyContent" required rows="4" cols="80"><%=replyDto.getReplyContent()%></textarea>
					<input type="submit" value="수정">
					<a class="edit-cancel-btn">취소</a>
				</form>
			</td>
		</tr>
	<%} %>

 

- ReplyDao 댓글 수정 기능 만들기

public boolean edit(ReplyDto replyDto) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "update reply set reply_content = ? where reply_no = ?";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setString(1, replyDto.getReplyContent());
	ps.setInt(2, replyDto.getReplyNo());
	int result = ps.executeUpdate();

	con.close();

	return result > 0;
}

 

 

- 댓글 수정 처리 (BoardReplyEditServlet.java) 만들기

package home.servlet.board;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import home.beans.ReplyDao;
import home.beans.ReplyDto;

@WebServlet(urlPatterns = "/board/reply/edit.txt")
public class BoardReplyEditServlet extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//입력 : ReplyDto(replyNo + replyContent + boardNo)
			ReplyDto replyDto = new ReplyDto();
			replyDto.setReplyNo(Integer.parseInt(req.getParameter("replyNo")));
			replyDto.setReplyContent(req.getParameter("replyContent"));
			replyDto.setBoardNo(Integer.parseInt(req.getParameter("boardNo")));

			//처리 : 수정 ( + 댓글 수 갱신 불필요)
			ReplyDao replyDao = new ReplyDao();
			boolean success = replyDao.edit(replyDto);

			//출력 : 게시글 상세페이지 redirect
			if(success) {
				resp.sendRedirect("../detail.jsp?boardNo="+replyDto.getBoardNo());
				//resp.sendRedirect(req.getContextPath()+"/board/detail.jsp?boardNo="+replyDto.getBoardNo());
			}
			else {
				resp.sendError(404);
			}

		}
		catch(Exception e) {
			e.printStackTrace();
			resp.sendError(500);
		}
	}
}

 

- 댓글 수정 기능 구현 완료

 

[ 댓글 수정 기능 추가 ( 나중에 배울 내용 ) ]

- 게시판 상세보기 (detail.jsp) 추가 하기

<%-- 번외 : 수정 버튼을 눌렀을 때 처리되도록 구현하는 스크립트(나중에 배움) --%>
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script>
	$(function(){
		$(".view-row").find(".edit-btn").click(function(){
			$(this).parents("tr.view-row").hide();
			$(this).parents("tr.view-row").next("tr.edit-row").show();
		});
		
		$(".edit-row").find(".edit-cancel-btn").click(function(){
			$(this).parents("tr.edit-row").hide();
			$(this).parents("tr.edit-row").prev("tr.view-row").show();
		});
		
		$(".edit-row").hide();
	});
</script>

 

[ 수정 버튼 누르기 전 ]

[ 수정 버튼 누르기 후 ]

 

 

 

홈페이지 - 계층형 게시판

[ 계층형 게시판의 원리 ]

 

 

 

- BoardDao 계층형 목록(Tree) 기능 만들기

public List<BoardDto> listByTreeSort(int begin, int end) throws Exception {
	Connection con = JdbcUtils.connect2();

	String sql = "select * from ("
				+ "select rownum rn, TMP.* from ("
					+ "select * from board "
					+ "connect by prior board_no = board_superno "
					+ "start with board_superno is null "
					+ "order siblings by board_groupno desc, board_no asc"
				+ ")TMP"
			+ ") where rn between ? and ?";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, begin);
	ps.setInt(2, end);
	ResultSet rs = ps.executeQuery();

	List<BoardDto> list = new ArrayList<>();
	while(rs.next()) {
		BoardDto boardDto = new BoardDto();

		boardDto.setBoardNo(rs.getInt("board_no"));
		boardDto.setBoardWriter(rs.getString("board_writer"));
		boardDto.setBoardTitle(rs.getString("board_title"));
		boardDto.setBoardContent(rs.getString("board_content"));
		boardDto.setBoardTime(rs.getDate("board_time"));
		boardDto.setBoardRead(rs.getInt("board_read"));
		boardDto.setBoardReply(rs.getInt("board_reply"));
		boardDto.setBoardSuperno(rs.getInt("board_superno"));
		boardDto.setBoardGroupno(rs.getInt("board_groupno"));
		boardDto.setBoardDepth(rs.getInt("board_depth"));

		list.add(boardDto);
	}

	con.close();

	return list;
}

 

- 페이징 모듈 Pagination 수정 하기

[ 수정 전 코드 ]

//list 계산
if(this.isSearch()) {
	this.list = boardDao.searchByRownum(column, keyword, begin, end);
}
else {
		this.list = boardDao.listByRownum(begin, end);//일반
	}
}

 

[ 수정 후 코드 ]

//list 계산
if(this.isSearch()) {
	this.list = boardDao.searchByRownum(column, keyword, begin, end);
}
else {
		this.list = boardDao.listByTreeSort(begin, end);//계층형
	}
}

 

- SQL 상위게시글번호, 그룹, 차수 위에 이미지 처럼 설정하기 

insert into board values(1, 'homemaster', '첫 번째 글', '첫 번째 글', sysdate, 0, 0, null, 1, 0);
insert into board values(2, 'homemaster', '두 번째 글', '두 번째 글', sysdate, 0, 0, null, 2, 0);
insert into board values(3, 'homemaster', '세 번째 글', '세 번째 글', sysdate, 0, 0, null, 3, 0);
insert into board values(4, 'homemaster', '네 번째 글', '네 번째 글', sysdate, 0, 0, null, 4, 0);
insert into board values(5, 'homemaster', '다섯 번째 글', '다섯 번째 글', sysdate, 0, 0, 3, 3, 1);
insert into board values(6, 'homemaster', '여섯 번째 글', '여섯 번째 글', sysdate, 0, 0, 3, 3, 1);
insert into board values(7, 'homemaster', '일곱 번째 글', '일곱 번째 글', sysdate, 0, 0, 5, 3, 2);
insert into board values(8, 'homemaster', '여덟 번째 글', '여덟 번째 글', sysdate, 0, 0, 4, 4, 1);
insert into board values(9, 'homemaster', '아홉 번째 글', '아홉 번째 글', sysdate, 0, 0, null, 9, 0);
insert into board values(10, 'homemaster', '열 번째 글', '열 번째 글', sysdate, 0, 0, 3, 3, 1);
commit;

 

- BoardDto 답변글인지 확인하는 메소드 추가

public boolean hasDepth() {
	return this.boardDepth > 0;
}

 

- 게시판 목록 (list.jsp) 수정하기

게시글의 제목을 출력하기 전에 차수에 따라 띄어쓰기를 진행한다
띄어쓰기는 HTML 특수문자인 &nbsp; 을 사용한다.
답변글에는 reply icon을 추가로 출력한다. 

[ 수정 전 코드 ]

<table border="1" width="90%">
	<thead>
		<tr>
			<th>번호</th>
			<th width="45%">제목</th>
			<th>작성자</th>
			<th>작성일</th>
			<th>조회수</th>
		</tr>
	</thead>
	<tbody align="center">
		<%for(BoardDto boardDto : pagination.getList()){ %>
		<tr>
			<td><%=boardDto.getBoardNo()%></td>
			<td align="left">
				<a href="detail.jsp?boardNo=<%=boardDto.getBoardNo()%>">
					<%=boardDto.getBoardTitle()%>
				</a>

				<!-- 제목 뒤에 댓글 개수를 출력한다 -->
				<%
				//if(boardDto.getBoardReply() > 0){
				if(boardDto.isReplyExist()){
				%>
					[<%=boardDto.getBoardReply()%>]
				<%} %>
			</td>
			<td><%=boardDto.getBoardWriter()%></td>
			<td><%=boardDto.getBoardTime()%></td>
			<td><%=boardDto.getBoardRead()%></td>
		</tr>
		<%} %>
	</tbody>
</table>

 

[ 수정 후 코드 ]

<table border="1" width="90%">
	<thead>
		<tr>
			<th>번호</th>
			<th width="40%">제목</th>
			<th>작성자</th>
			<th>작성일</th>
			<th>조회수</th>
			<th>상위글</th>
			<th>그룹</th>
			<th>차수</th>
		</tr>
	</thead>
	<tbody align="center">
		<%for(BoardDto boardDto : pagination.getList()){ %>
		<tr>
			<td><%=boardDto.getBoardNo()%></td>
			<td align="left">
			
				<%
					//if(boardDto.getBoardDepth() > 0){
					if(boardDto.hasDepth()){ 
				%>
					<%for(int i=0; i < boardDto.getBoardDepth(); i++){ %>
					&nbsp;&nbsp;&nbsp;&nbsp;
					<%} %>

					<img src="<%=request.getContextPath()%>/resource/image/reply.png" width="15" height="15">
				<%} %>
				<a href="detail.jsp?boardNo=<%=boardDto.getBoardNo()%>">
					<%=boardDto.getBoardTitle()%>
				</a>

				<!-- 제목 뒤에 댓글 개수를 출력한다 -->
				<%
				//if(boardDto.getBoardReply() > 0){
				if(boardDto.isReplyExist()){
				%>
					[<%=boardDto.getBoardReply()%>]
				<%} %>
			</td>
			<td><%=boardDto.getBoardWriter()%></td>
			<td><%=boardDto.getBoardTime()%></td>
			<td><%=boardDto.getBoardRead()%></td>
			<td><%=boardDto.getBoardSuperno()%></td>
			<td><%=boardDto.getBoardGroupno()%></td>
			<td><%=boardDto.getBoardDepth()%></td>
		</tr>
		<%} %>
	</tbody>
</table>

 

- 예상 이미지 구현 완료

 

 

 

- BoardDao 등록 기능 수정 하기

[ 수정 전 코드 ]

public void write2(BoardDto boardDto) throws Exception{
	Connection con = JdbcUtils.connect(USERNAME, PASSWORD);

	String sql = "insert into board values(?, ?, ?, ?, sysdate, 0, 0, 0, 0, 0)";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, boardDto.getBoardNo());
	ps.setString(2, boardDto.getBoardWriter());
	ps.setString(3, boardDto.getBoardTitle());
	ps.setString(4, boardDto.getBoardContent());
	ps.execute();

	con.close();
}

 

[ 수정 후 코드 ]

public void write2(BoardDto boardDto) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "insert into board values(?, ?, ?, ?, sysdate, 0, 0, null, 0, 0)";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, boardDto.getBoardNo());
	ps.setString(2, boardDto.getBoardWriter());
	ps.setString(3, boardDto.getBoardTitle());
	ps.setString(4, boardDto.getBoardContent());
	ps.setInt(5, boardDto.getBoardNo());
	ps.execute();

	con.close();
}

 

 

- 게시판 상세보기 (detail.jsp) 수정하기

[ 수정 전 코드 ]

<a href="write.jsp">글쓰기</a>
<a href="list.jsp">목록보기</a>

 

[ 수정 후 코드 ]

<a href="write.jsp">글쓰기</a>
<a href="write.jsp?boardSuperno=<%=boardDto.getBoardNo()%>">답글쓰기</a>
<a href="list.jsp">목록보기</a>

 

- 게시글 작성 (write.jsp) 수정하기

[ 수정 전 코드 ]

<%-- 입력 --%>

<%-- 처리 --%>

<%-- 출력 --%>
<jsp:include page="/template/header.jsp"></jsp:include>

<h2>게시글 작성</h2>

<form action="write.txt" method="post">

<table border="0">

 

[ 수정 후 코드 ]

<%-- 입력 : 답글일 경우에는 boardSuperno라는 값이 전달된다. --%>
<%
	String boardSuperno = request.getParameter("boardSuperno");
%>

<%-- 처리 --%>
<%
	boolean answer = boardSuperno != null;
	String title = answer ? "답글 작성" : "새글 작성";
%>

<%-- 출력 --%>
<jsp:include page="/template/header.jsp"></jsp:include>

<h2><%=title%></h2>

<form action="write.txt" method="post">

<%-- 답글일 경우에는 반드시 "상위글번호(boardSuperno)" 를 처리페이지로 전송해야 한다 --%>
<%if(answer){ %>
<input type="hidden" name="boardSuperno" value="<%=boardSuperno%>">
<%} %>

<table border="0">

 

- 글쓰기 -> 새글 작성 / 답글쓰기 -> 답글 작성 구현 완료

 

- BoardDao 게시글 등록(답글) 기능 만들기

public void writeAnswer(BoardDto boardDto) throws Exception{
	Connection con = JdbcUtils.connect2();

	String sql = "insert into board values(?, ?, ?, ?, sysdate, 0, 0, ?, ?, ?)";
	PreparedStatement ps = con.prepareStatement(sql);
	ps.setInt(1, boardDto.getBoardNo());
	ps.setString(2, boardDto.getBoardWriter());
	ps.setString(3, boardDto.getBoardTitle());
	ps.setString(4, boardDto.getBoardContent());
	ps.setInt(5, boardDto.getBoardSuperno());//계산된 상위글번호
	ps.setInt(6, boardDto.getBoardGroupno());//계산된 그룹번호(원본글 그룹번호와 동일)
	ps.setInt(7, boardDto.getBoardDepth());//계산된 차수(원본글 차수 + 1)
	ps.execute();

	con.close();
}

 

- 등록 처리 (BoardWriteServlet.java) 수정하기

[ 수정 전 코드 ]

//아이디는 세션에서 수집하여 추가
	boardDto.setBoardWriter((String)req.getSession().getAttribute("ses"));

	//처리
	//(1) 일반적인 등록
	//BoardDao boardDao = new BoardDao();
	//boardDao.write(boardDto);

	//(2) 번호를 알아내면서 등록
	BoardDao boardDao = new BoardDao();
	int boardNo = boardDao.getSequence();//시퀀스 번호 생성
	boardDto.setBoardNo(boardNo);//게시글 데이터에 생성된 번호 추가
	boardDao.write2(boardDto);//게시글 등록
    
 //출력

 

[ 수정 후 코드 ]

//아이디는 세션에서 수집하여 추가
	boardDto.setBoardWriter((String)req.getSession().getAttribute("ses"));
			
//새글인지 답글인지 판정 : 파라미터에 boardSuperno가 있으면 답글이다
	boolean answer = req.getParameter("boardSuperno") != null;
	//답글일 경우에는 boardSuperno를 저장한다.
	if(answer) {
		boardDto.setBoardSuperno(Integer.parseInt(req.getParameter("boardSuperno")));
	}

	//처리
	//(1) 일반적인 등록
	//BoardDao boardDao = new BoardDao();
	//boardDao.write(boardDto);

	//(2) 번호를 알아내면서 등록
	BoardDao boardDao = new BoardDao();
	int boardNo = boardDao.getSequence();//시퀀스 번호 생성
	boardDto.setBoardNo(boardNo);//게시글 데이터에 생성된 번호 추가
	//답글일 경우 등록될 글의 정보를 상위글 정보를 기준으로 계산해야 한다.
	if(answer) {
		//1. 상위글의 모든 정보를 불러온다
		BoardDto parentDto = boardDao.get(boardDto.getBoardSuperno());
		//2. 상위글의 정보를 토대로 등록될 글의 정보를 계산한다
		//= 그룹은 동일하게 유지하고 차수는 1 증가시켜서 설정한다
		boardDto.setBoardGroupno(parentDto.getBoardGroupno());
		boardDto.setBoardDepth(parentDto.getBoardDepth() + 1);
		boardDao.writeAnswer(boardDto);//게시글 등록(답글)
	}else{
		boardDao.write2(boardDto);//게시글 등록(새글)
	}

//출력

 

- 답글 구현 완료