today_is
[ jsp ] 회원 + 게시판 본문
오늘의 목표
회원, 게시판 생성하여 게시판 기능을 만들어보자
Member 테이블
컬럼명 | null 여부 | 데이터 타입 | |
IDX | NOT NULL | NUMBER | primary key |
USERID | NOT NULL | VARCHAR2(100) | unique |
USERPW | NOT NULL | VARCHAR2(500) | |
USERNAME | NOT NULL | VARCHAR2(100) | |
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
: 게시판 기능을 처리해줄 함수들
package board;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
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
: 모든 페이지에 적용할 태그선언과 링크를 작성함
다른 페이지에서는 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 에 method 를 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 을 위치시킴 (== 댓글)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<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>
study_review
오늘은 크게 실수하는 것 없이 잘 수행했다
아쉬운 점이라면,
게시물 상세보기를 빠져나가는 버튼을 만들지 않은 것을 지금 발견했다 ㅋㅋㅋㅋㅋ
view.jsp 하단에
<a href="${cpath }/board.jsp"><button>목록으로</button></a> 를 추가하면 좋을듯하다 !
'java' 카테고리의 다른 글
[ jsp ] MVC 패턴 (0) | 2023.12.24 |
---|---|
[ jsp ] 회원 + 게시판 + 댓글 (0) | 2023.12.16 |
[ jsp ] 회원기능 구현 (2) - 수정, 삭제 (0) | 2023.12.12 |
[ jsp ] 회원기능 구현 (1) - 회원가입, 로그인, 로그아웃 (0) | 2023.12.12 |
[ jsp ] 로그인 세션 (0) | 2023.12.11 |