[JSP] 게시판 (1)

2024. 10. 7. 18:25JSP

오늘은 회원과 게시판 기능을 함께 합쳐서 만들어 보자.

 


Member 테이블 

컬럼명 null 여부 데이터 타입  
IDX NOT NULL NUMBER primary key
USERID NOT NULL VARCHAR2(100) unique
USERPW NOT NULL VARCHAR2(500)  
USERNAME NOT NULL VARCHAR2(100)  
EMAIL NOT NULL VARCHAR2(100)  
GENDER   VARCHAR2(50)  

 

Board 테이블

컬럼명 null 여부 데이터 타입 참조  
IDX  NOT NULL  NUMBER   primary key
TITLE  NOT NULL  VARCHAR2(500)    
WRITER  NOT NULL VARCHAR2(100) member 테이블의 userid 참조  
CONTENT  NOT NULL VARCHAR2(4000)    
WRITEDATE   DATE    

 

MemberDTO & BoardDTO

getter, setter를 생성해 준다.

 

BoardDAO

게시판 기능을 처리해줄 함수들 작성.

public class BoardDAO {
	private Connection conn;
	private PreparedStatement pstmt;
	private ResultSet rs;
	
	private Context init;
	private DataSource ds;
	
	private static BoardDAO instance = new BoardDAO();
	public static BoardDAO getInstance() {
		return instance;
	}
	private BoardDAO() {
		try {
			init = new InitialContext();
			ds = (DataSource) init.lookup("java:comp/env/jdbc/oracle");
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}
	
	private void close() {
		try {
			if(rs != null) 		rs.close();
			if(pstmt != null) 	pstmt.close();
			if(conn != null) 	conn.close();
		}catch(SQLException e) {}
	}
	
	private BoardDTO mapping(ResultSet rs) throws SQLException {
		BoardDTO dto = new BoardDTO();
		dto.setContent(rs.getString("content"));
		dto.setIdx(rs.getInt("idx"));
		dto.setTitle(rs.getString("title"));
		dto.setWriteDate(rs.getDate("writeDate"));
		dto.setWriter(rs.getString("writer"));
		return dto;
	}
	
	// 게시글 목록
	public List<BoardDTO> selectList() {
		ArrayList<BoardDTO> list = new ArrayList<>();
		String sql = "select "
				+ " (select count(*) from reply where board_idx = board.idx) as replyCount,"
				+ " board.* "
				+ " from board order by idx desc";	// 최신글이 위에 노출되도록
		try {
			conn = ds.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				BoardDTO dto = mapping(rs);				// 기본 맵핑 + 
				dto.setReplyCount(rs.getInt("replyCount")); // 댓글 개수
				list.add(dto);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally { close(); }
		return list;
	}
	
	// 게시글 조회
	public BoardDTO selectOne(int idx) {
		BoardDTO dto = null;
		String sql = "select * from board where idx = ?";
		try {
			conn = ds.getConnection();
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, idx);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				dto = mapping(rs);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally { close(); }
		return dto;
	}
	
	// 게시글 작성
	public int insert(BoardDTO dto) {
		int row = 0;
		String sql = "insert into board (title, writer, content) "
				+ "	values (?, ?, ?)";
		try {
			conn = ds.getConnection();
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getTitle());
			pstmt.setString(2, dto.getWriter());
			pstmt.setString(3, dto.getContent());
			row = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally { close(); }
		return row;
	}	
}

 

header.jsp

모든 페이지에 적용할 태그 선인 및 링크 등을 작성해준다.

다른 모든 페이지들에 include하여 사용.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="member.*, board.*, reply.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="cpath" value="${pageContext.request.contextPath }" />
<c:set var="memberDAO" value="${MemberDAO.getInstance() }" />
<c:set var="boardDAO" value="${BoardDAO.getInstance() }" />
<c:set var="replyDAO" value="${ReplyDAO.getInstance() }" />

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>day16 - board</title>
</head>
<body>

<header>
	<h1><a href="${cpath }">day16 - board</a></h1>
	<div style="text-align: right; padding-right: 20px; height: 30px;">
		${login.userid }
	</div>
	<nav>
		<ul style="display: flex; list-style: none; justify-content: space-around;">
			<li><a href="${cpath }/login.jsp">로그인</a></li>
			<li><a href="${cpath }/logout.jsp">로그아웃</a></li>
			<li><a href="${cpath }/join.jsp">회원가입</a></li>
			<li><a href="${cpath }/board.jsp">게시판</a></li>
		</ul>
	</nav>
</header>

 

board.jsp

boardDAO에 있는 selectList() 함수를 이용하여 게시판 목록을 보여준다.

c:forEach를 이용하여 게시글을 1개씩 보여줄 수 있도록 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<h3>게시판</h3>

<table border="1" cellpadding="10" cellspacing="0" width="800" align="center">
	<c:set var="list" value="${boardDAO.selectList() }" />
	<c:forEach var="dto" items="${list }">
	<tr>
		<td>${dto.idx }</td>
		<td width="500">
			<a href="${cpath }/view.jsp?idx=${dto.idx}">${dto.title }</a>
			<c:if test="${dto.replyCount != 0 }">
				<span style="color: red;
				font-size: 13px;">[${dto.replyCount }]</span>
			</c:if>
		</td>
		<td>${dto.writer }</td>
		<td>${dto.writeDate }</td>
	</tr>
	</c:forEach>
</table>

<div style="display: flex; width: 800px; margin: 20px auto; justify-content: space-between;">
	<div>
	
	</div>
	<div>
		<a href="${cpath }/write.jsp"><button>작성</button></a>
	</div>
</div>

</body>
</html>

 

write.jsp

만약 메서드가 GET이면서 로그인이 되어 있지 않는 상태라면, alert으로 '로그인 후 작성 가능' 을 띄우고 login.jsp로 이동 시킨다.

form에 mothod를 POST로 하고, form을 작성하게 한다.

form을 제출하면 boardDAO에 있는 insert() 함수를 이용하여 게시글을 추가로 생성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>

<c:if test="${pageContext.request.method == 'GET' }">
	<c:if test="${empty login }">
		<script>
			alert("먼저 로그인 후 글을 작성할 수 있습니다")
			location.href = '${cpath}/login.jsp'
		</script>
	</c:if>
	<form method="POST">
		<p><input type="text" name="title" placeholder="제목" required autofocus></p>
		<input type="hidden" name="writer" value="${login.userid }">
		<p>
			<textarea name="content" placeholder="내용" rows="8" cols="60" required></textarea>
		</p>
		<p><input type="submit" value="작성하기"></p>
	</form>
</c:if>

<c:if test="${pageContext.request.method == 'POST' }">
	<jsp:useBean id="dto" class="board.BoardDTO" />
	<jsp:setProperty property="*" name="dto"/>
	<c:set var="row" value="${boardDAO.insert(dto) }" />
	<c:redirect url="/board.jsp" />
</c:if>

</body>
</html>

 

view.jsp

게시글 상세 보기

boardDAO에 있는 selectOne() 함수를 이용하여 특정된 1개의 게시물을 볼 수 있도록 한다.

각 게시물 밑에는 form을 위치시킨다. (댓글)

<h3>게시글 상세 보기</h3>

<fieldset>
	<c:set var="dto" value="${boardDAO.selectOne(param.idx) }" />
	<h4>${dto.title } | ${dto.writer } | ${dto.writeDate }</h4>
	<pre>${dto.content }</pre>
</fieldset>
<br>

<form method="POST" action="reply-write.jsp">
	<h3>댓글 작성</h3>
	<c:if test="${empty login }">
		<c:set var="replyComment">로그인 후에 댓글 작성 가능합니다</c:set>
	</c:if>
	<c:if test="${not empty login }">
		<c:set var="replyComment">바르고 고운 말을 사용합시다</c:set>
	</c:if>
	<div style="display: flex; align-items: center;">
		<textarea name="content" rows="5" cols="80"
				  placeholder="${replyComment }" ${empty login ? 'disabled' : '' }
				  style="resize: none;
				  		 height: 100px;
				  		 padding: 10px;
				  		 box-sizing: border-box;"></textarea>
		<input type="submit" value="댓글쓰기"
			   ${empty login ? 'disabled' : '' }
			   style="margin: 10px;
			   		  height: 100px;">
	</div>
	<input type="hidden" name="board_idx" value="${param.idx }">
	<input type="hidden" name="writer" value="${login.userid }">
</form>

<div id="reply">
	<c:forEach var="reply" items="${replyDAO.selectList(param.idx) }">
	<div class="replyItem" style="border: 1px solid grey; 
				margin: 20px;
				padding: 10px;
				box-sizing: border-box;">
		<div style="display: flex; justify-content: space-between;">
			<div>${reply.writer }</div>
			<div><fmt:formatDate value="${reply.writeDate }" pattern="yyyy-MM-dd a hh:mm" /></div>
		</div>
		<div>
			<pre>${reply.content }</pre>
			<c:if test="${reply.writer == login.userid }">
				<a href="${cpath }/reply-delete.jsp?idx=${reply.idx}&board_idx=${dto.idx}">
					<button>댓글 삭제</button>
				</a>
			</c:if>
		</div>
	</div>
	</c:forEach>
</div>

</body>
</html>

 


이제 제법 사이트라고 할 만한 것들을 만들게 되니까 더 재밌어진다.

자바와 html, DB 3개를 연동 하는 것이 익숙해지도록 전체 틀을 먼저 이해하는 것이 중요하다.

'JSP' 카테고리의 다른 글

[JSP] MVC  (1) 2024.10.09
[JSP] 게시판 (2)  (1) 2024.10.07
[JSP] 회원 기능 (2)  (0) 2024.10.07
[JSP] 회원 기능 (1)  (0) 2024.10.05
[JSP] Login Session  (1) 2024.10.05