JSP/model 1

답글 기능을 포함한 게시판 (2) - 본문, 글목록

Kiwisae 2022. 9. 8. 12:46
  • DBCP 방식 사용,
  • 액션태그 사용 (useBean, setProperty)
  • DTO, DAO 클래스
  • 페이징 처리 (inline view)
  • 답글 처리

 

 

프로그램 구조

 

Java Resources >
src > board
DTO 클래스 BoardDataBean.java  
DAO 클래스 BoardDBBean.java  
WebContent > reboard reboard writeForm.jsp  
writePro.jsp  
list.jsp  
content.jsp  
replyForm.jsp  
replyPro.jsp  
updateForm.jsp  
updatePro.jsp  
deleteFrom.jsp  
deletePro.jsp  
META-INF context.xml 커넥션 풀 환경설정 파일
WEB-INF > lib ojdbc6.jar  
  web.xml 프로젝트 환경설정 파일

 

 

 

 

 

1. 본문 (부모글) writeForm.jsp

 

다음과 같은 형태이다.

 

 

 

 

action 값은 writePro.jsp로 설정하고

이 화면에서 사용자에게 입력받지 않는 num, ref, re_step, re_level은 hidden 객체를 생성해 넘긴다.

 

<% 
  int num=0,ref=1,re_step=0,re_level=0;
%>

<input type="hidden" name="num" value="<%=num%>">
<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%>">

 

 

 

2. writePro.jsp

 

한글 인코딩 설정과 useBean, setProperty 액션 태그를 제일 먼저 설정한다.

 

<%
	request.setCharacterEncoding("UTF-8");
%>

<jsp:useBean id="board" class="reboard.BoardDataBean"/>
<jsp:setProperty property="*" name="board"/>

 

 

 

 

기본 자료형 변수들은 값이 0으로 할당되어 액션태그로 값이 넘어오지만

날짜/시간인 reg_date와 ip는 따로 값을 지정해주어야 한다.

 

request 객체로 ip 값을 구해 String형 변수 ip에 저장한다.

 

<%
	String ip = request.getRemoteAddr();
	board.setIp(ip);
%>

 

 

 

 

 

3. writePro.jsp에 DAO 객체 생성

 

본문 글이 잘 작성되면 insert 메소드가 작동하고 return으로 int형 1을 돌려받는다.

return 값이 1이라면 if문이 동작한다.

이 내용을 미리 작성해놓고 DAO 문서에 insert 메소드를 작성한다.

 

<% 
	BoardDBBean dao = BoardDBBean.getInstance();
	int result = dao.insert(board);
	
	if (result == 1) { //본문글 작성이 잘 된 경우  %>
		<script>
			alert("글 작성 성공");
			location.href="list.jsp";	//게시판 글 목록
		</script>

<% } else { 						//본문글 작성 실패 
%>	
		<script>
			alert("글 작성 실패");
			history.go(-1);			//게시판 글 목록
		</script>

<% } %>

 

 

 

 

4. insert 메소드 생성

 

	public int insert(BoardDataBean board) {
		int result = 0;
		
		Connection con = null;
		PreparedStatement pstmt = null;
		
		try {
			con = getConnection();
			
			String sql = "insert into board values(board_seq.nextval,?,?,?,?, ";
					sql += " sysdate,?,board_seq.nextval,?,?,?,?)";
					
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, board.getWriter());
			pstmt.setString(2, board.getEmail());
			pstmt.setString(3, board.getSubject());
			pstmt.setString(4, board.getPasswd());
			pstmt.setInt(5, 0); // readCount
			pstmt.setInt(6, 0); // re_step
			pstmt.setInt(7, 0);	// re_level
			pstmt.setString(8, board.getIp());
			pstmt.setString(9, board.getContent());
			
			result = pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) try { pstmt.close();} catch (Exception e) {}
			if (con != null) try { con.close();} catch (Exception e) {}
		}
		
		return result;
	}

 

1) SQL 문안에 시퀀스 증가 함수가 num 컬럼과 ref 컬럼 이렇게 두 번 들어가 있는데,

같은 SQL 문이기 때문에 시퀀스 증가가 두 번 되는 것은 아니다.

num 컬럼과 ref 컬럼의 값을 검색해보면 다음과 같이 같은 값이 들어가있다.

 

 

 

2) readCount의 초기값은 0이기 때문에 값을 0으로 지정해도 상관없고,

board.getReadcount() 형식으로 넣어도 상관없다. (어차피 0으로 이미 초기화 되어 있음0

 

 

 

 

 

5. list.jsp 생성

 

1) 1페이지를 출력할 때, 한 화면에 출력되는 글의 개수

 

<%
	int page_size = 10;
	
	String pageNum = request.getParameter("page");
	if( pageNum == null ) {
		pageNum = "1";
	}
%>

 

 

2)

currentPage : 현재 페이지 번호

startRow : 각 페이지에 추출할 데이터의 시작번호

endRow : 각 페이지에 추출할 데이터의 끝 번호

 

1page : startRow=1, endRow=10

2page : startRow=11, endRow=20

epage : startRow=21, endRow=30 

.

.

<%
	int currentPage = Integer.parseInt(pageNum);

	int startRow = (currentPage - 1) * page_size + 1;
	int endPage = currentPage * page_size;
%>

 

 

3) 

count : 총 데이터 개수

 

<%
	int count = 0;

	BoardDBBean dao = BoardDBBean.getInstance();
	count = dao.getCount();
	System.out.println("count : "+count);
%>

 

아직은 list의 껍데기를 만들지 못했으므로 콘솔창에 출력시키도록 한다.

 

 

 

6. getCount 메소드 생성

 

 

	public int getCount() {
		int result = 0;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			con = getConnection();
			
			String sql = "select count(*) from board";
			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			
			if(rs.next()) {
				result = rs.getInt("count(*)");
//				result = rs.getInt(1);
			} // if end
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) try { rs.close();} catch (Exception e) {}
			if (pstmt != null) try { pstmt.close();} catch (Exception e) {}
			if (con != null) try { con.close();} catch (Exception e) {}
		}
		return result;
	}

 

잘 실행된다.

 

 

 

 

 

7.  리스트 생성

DB들을 리스트에 저장하여 순차적으로 불러오는 역할을 한다.

역시 껍데기를 만들지 않았으므로 콘솔창에 출력해볼 Systme.out.println까지 추가한다.

 

<%
	List<BoardDataBean> list = null;
	if (count>0) {
		list = dao.getList(startRow, endRow);
	}
	System.out.println("list : "+list);
%>

 

 

 

8. getList 메소드 작성

 

	public List<BoardDataBean> getList (int start, int end) {
		List<BoardDataBean> list = new ArrayList<BoardDataBean>();
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			con = getConnection();
			
			String sql = "select * from ( select rownum rnum, board.* from ";
				sql += " (select * from board order by ref desc, re_step asc) board) ";
				sql += " where rnum >= ? and rnum <= ?";
			
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, start);
			pstmt.setInt(2, end);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				BoardDataBean board = new BoardDataBean();
				
				board.setNum(rs.getInt("num"));
				board.setWriter(rs.getNString("wirter"));
				board.setEmail(rs.getString("email"));
				board.setSubject(rs.getString("subject"));
				board.setPasswd(rs.getNString("passwd"));
				board.setReg_date(rs.getTimestamp("reg_date"));
				board.setReadcount(rs.getInt("readcount"));
				board.setRef(rs.getInt("ref"));
				board.setRe_level(rs.getInt("re_level"));
				board.setRe_step(rs.getInt("re_step"));
				board.setContent(rs.getString("content"));
				board.setIp(rs.getString("ip"));
				
				list.add(board);
			} // while end
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) try { rs.close();} catch (Exception e) {}
			if (pstmt != null) try { pstmt.close();} catch (Exception e) {}
			if (con != null) try { con.close();} catch (Exception e) {}
		}
		
		return list;
	}

 

 

총 데이터 개수와 리스트의 주소값이 잘 출력된다.

 

 

 

 

 

9. 테이블 생성으로 데이터 출력

조건문으로 만약 총 데이터 개수가 0개라면 작성된 글이 없다는 메시지를 출력한다.

 

그러나 count가 0개 이상이라면

list에 저장한 로우 데이터를 for문으로 루프를 돌려 테이블에 한 행씩 추출한다

 

<% if (count == 0) { %>
		작성된 글이 없습니다.
<% } else { %>
		<a href="writeForm.jsp">글작성</a> 글개수: <%= count %>
		<table border=1 cellpadding=0 width=700 align=center bgcolor="#FAEBFF">
			<caption>    게   시   판   목   록         </caption>
			<tr>
				<th>글번호</th>
				<th>글제목</th>
				<th>작성자</th>
				<th>작성일</th>
				<th>조회수</th>
				<th>IP주소</th>
			</tr>
<%
	//number : 각 페이지에 출력될 시작 번호
	int number = count - (currentPage-1) * page_size;
	SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	for (int i=0; i<list.size(); i++) {
		BoardDataBean board = list.get(i);
%>
			<tr>
				<td><%= number-- %></td>
				<td><%= board.getSubject() %></td>
				<td><%= board.getWriter() %></td>
				<td><%= sd.format(board.getReg_date()) %></td>
				<td><%= board.getReadcount() %></td>
				<td><%= board.getIp() %></td>
			</tr>
<%		} // for end %>
		</table>
<% } //if end %>

 

 

이때, 출력되는 것이 답글일 경우에는 글제목이 들여쓰기 되도록 if문을 추가한다.

 

<%				if(board.getRe_level() > 0) {
					for(int j=1; j<board.getRe_level(); j++) { %>
						&nbsp;&nbsp;
<% 					} // for end %>

 

 

 

 

 

10. 페이지 링크 설정

 

pageCount : 총 페이지 수

block : 10개 페이지로 구성

 

1block = 페이지 10개

1page = 글 10개

 

startPage : 각 블럭의 시작 페이지 번호 : 1, 11, 21..

endPage : 각 블럭의 끝 페이지 번호 : 10, 20, 30 ...

 

가장 마지막 블럭은 pageCount값이 endPage 값이 되도록 중첩으로 if문을 넣는다.

 

<center>
<%
if(count > 0) {

	// pageCount: 총 페이지 수
	int pageCount = count/page_size + ((count%page_size == 0 ? 0 : 1));
	System.out.println("pageCount : "+pageCount);
	
	// startPage : 각 블럭의 시작 페이지 번호 : 1, 11, 21..
	// endPage : 각 블럭의 끝 페이지 번호 : 10, 20, 30 ...
	int block = 10;
	int startPage = ((currentPage-1)/10) * 10 + 1;
	int endPage = startPage + block - 1;
	
	// 가장 마지막 블럭에는 endPage 값을 pageCount값으로 수정
	if (endPage > pageCount ){
		endPage = pageCount;
	}
%>

	<!-- 1페이지로 이동 -->
	<a href="list.jsp?page=1" style="text-decoration:none"> << </a>
	
<%	// 이전 블럭으로 이동
	if (startPage>10) { %>
		<a href="list.jsp?page=<%= startPage-10 %>" style="text-decoration:none">[이전]</a>	
<% 	}
	//각 블록당 10개의 페이지 출력
	for (int i=startPage; i<=endPage; i++) {
		if (i == currentPage) {	// 현재 페이지 %>
			[<%= i %>]
<%		} else {	%>			// 현재 페이지가 아님
			<a href="list.jsp?page=<%= i %>">[<%= i %>]</a>
			
<% 		}
	} // for end
	
	// 다음 블럭으로 이동
	if(endPage < pageCount) { %>
		<a href="list.jsp?page=<%= startPage+10 %>" style="text-decoration:none">[다음]</a>	
<%	} %>
	
	<!-- 마지막 페이지로 이동 -->
	<a href="list.jsp?page=<%= pageCount %>" style="text-decoration:none"> >> </a>

<%
}
%>
</center>