[정보처리산업기사] 연습문제 – 게시판 및 댓글

정보처리산업기사

정보처리산업기사 과정형평가 연습문제 - 게시판 및 댓글을 분석하고 풀어보도록 하겠습니다.

연습문제 다운로드 : 정보처리 산업기사 연습문제 2

다음 내용을 선행학습 해주세요

  1. Oracle Database 11g Express Edition 설치
  2. [Oracle] table create, insert, select, update, delete ( CRUD )
  3. [Oracle] [Java] oracle과 java 연동
  4. [Oracle] [JSP] Oracle과 JSP 연동 및 CRUD
  5. [oracle][jsp] 정보처리산업기사 과정형평가 예상문제 연습

 

솔루션 다운로드 : Board0808.zip

 

문제분석

  1. 게시물 테이블 작성
  2. 댓글 테이블 작성
  3. 게시물에 대한 시퀀스 추가
  4. 댓글에 대한 시퀀스 추가
  5. 게시물 목록, 조회, 작성, 수정, 삭제 구현
  6. 댓글 조회, 삭제

 

테이블 명세서

board

board_tbl

-- 테이블 생성 전 권한부여
grant create table, create sequence to system;

-- 게시물 테이블 생성
create table board (
  idx number(6) primary key,  -- 번호
  writer varchar2(20),        -- 작성자
  subject varchar2(255),      -- 제목
  content clob,               -- 내용
  reg_date timestamp          -- 작성일
);

-- 생성 후 CRUD 권한부여
grant insert,update,delete,select on board to system;

-- 완료 후 커밋
commit;

 

comment_list

comment_tbl

-- 댓글 테이블 생성
create table comment_list (
  idx number(6) Primary Key,  -- 댓글 일련번호
  bidx number(6),             -- 게시물 번호
  writer varchar2(20),        -- 작성자
  content clob,               -- 내용
  reg_date timestamp          -- 작성일
);

-- 권한 부여
grant insert, update, delete, select on comment_list to system;


-- 완료 후 커밋
commit;

 

sequence 작성

-- 게시물에 대한 시퀀스 추가
create sequence board_seq
start with 1
increment by 1
minvalue 1
cache 10;

-- 댓글에 대한 시퀀스 추가
create sequence comment_seq
start with 1
increment by 1
minvalue 1
cache 10;

-- 시퀀스 권한 추가
grant alter, select on board_seq to system;
grant alter, select on comment_seq to system;


-- 완료 후 커밋
commit;

 

게시물 데이터 추가

-- 게시물 정보 추가
insert into sys.board values(sys.board_seq.nextval, '김회원', '정보처리 산업기사 쉽다', 'jsp 쉽네요', '2018-07-31 12:34:56');
insert into sys.board values(sys.board_seq.nextval, '김회원', '웹 디자인 기능사 어렵다', 'jquery 어렵네요', '2018-07-31 12:43:43');
insert into sys.board values(sys.board_seq.nextval, '이회원', '정보처리 산업기사 어렵다', 'jsp 어렵네요', '2018-08-01 13:34:56');
insert into sys.board values(sys.board_seq.nextval, '이회원', '정보처리 산업기사 쉽다', 'jquery 쉽네요', '2018-08-01 13:43:34');
insert into sys.board values(sys.board_seq.nextval, '박회원', 'ㅈㄱㄴ', '제목 그대로 내용', '2018-08-02 13:12:10');
insert into sys.board values(sys.board_seq.nextval, '박회원', '제목 그대로 내용', 'ㅈㄱㄴ', '2018-08-03 14:34:20');
insert into sys.board values(sys.board_seq.nextval, '강회원', '하드코딩하는 사람들', '가입하면 좋음', '2018-08-04 14:56:30');
insert into sys.board values(sys.board_seq.nextval, '나회원', 'github를 사용합시다', '신세계', '2018-08-05 15:43:35');
insert into sys.board values(sys.board_seq.nextval, '문회원', '노는 게 제일좋아', '모두들 모여라', '2018-08-06 16:21:40');
insert into sys.board values(sys.board_seq.nextval, '지회원', '여름아', '부탁해', '2018-08-07 17:01:45');

commit;

 

댓글 데이터 추가

-- 댓글 정보 추가
insert into sys.comment_list values(sys.comment_seq.nextval, '1', '김회원', 'Lorem ipsum dolor sit amet', '2018-08-01 12:34:56');
insert into sys.comment_list values(sys.comment_seq.nextval, '3', '김회원', 'consectetur adipiscing elit', '2018-08-01 12:43:43');
insert into sys.comment_list values(sys.comment_seq.nextval, '5', '이회원', 'sed do eiusmod tempor', '2018-08-02 13:34:56');
insert into sys.comment_list values(sys.comment_seq.nextval, '7', '이회원', 'incididunt ut labore et ', '2018-08-03 13:43:34');
insert into sys.comment_list values(sys.comment_seq.nextval, '9', '박회원', 'dolore magna aliqua', '2018-08-04 13:12:10');
insert into sys.comment_list values(sys.comment_seq.nextval, '2', '박회원', 'minim veniam, quis nostrud ', '2018-08-04 14:34:20');
insert into sys.comment_list values(sys.comment_seq.nextval, '3', '강회원', 'exercitation ullamco laboris ', '2018-08-05 14:56:30');
insert into sys.comment_list values(sys.comment_seq.nextval, '5', '나회원', 'nisi ut aliquip ', '2018-08-06 15:43:35');
insert into sys.comment_list values(sys.comment_seq.nextval, '7', '문회원', 'ex ea commodo consequat', '2018-08-07 16:21:40');
insert into sys.comment_list values(sys.comment_seq.nextval, '2', '지회원', 'Duis aute irure dolor', '2018-08-07 17:01:45');

commit;

이렇게 쿼리문을 작성해야합니다.

 

JSP 코드 작성

1. dbConnection.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%
    /* 한글 깨짐 방지 */
    request.setCharacterEncoding("UTF-8");

    /* DB 접속 */
    String user = "system"; // oracle 계정
    String pw = "oracle";   // oracle 비밀번호
    String url = "jdbc:oracle:thin:@localhost:1521:xe"; // 그대로 사용
    String sql = "";
    Class.forName("oracle.jdbc.driver.OracleDriver");
    Connection conn = DriverManager.getConnection(url, user, pw);
%>

dbConnection.jsp를 모든 페이지 상단에서 include 합니다. 더 정확히 표현하자면, header.jsp에서 dbConnection.jsp를 include하고, header를 모든 페이지에서 include 함으로써 중복 작성을 최대한 줄일 수 있습니다.

 

2. header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="dbConnection.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>쇼핑몰 회원 관리 Ver 1.0</title>
</head>
<body>
    <div class="header">
        <h3 class="logo">커뮤니티 사이트</h3>
        <div class="gnb">
            <ul>
                <li><a href="./index.jsp">게시판</a></li>
            </ul>
        </div>
    </div>
    <div class="container">
        <div class="content">

header에서 사이트 상단에 공통적으로 보여질 내용을 작성합니다. 사실 현재 과제에선 딱히 필요 없으나, 형식적으로 작성하였습니다.

 

3. footer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
        </div>
    </div>
    <footer class="footer">
        copyright &copy; 2018 junil.hwang all right reserved.
    </footer>
</body>
</html>

footer에는 copyright를 명시합니다.

 

4. index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="header.jsp" %>
<%
    /* next value 가져오기 */
    sql = "SELECT count(*) as cnt from sys.board";
    ResultSet res = conn.prepareStatement(sql).executeQuery();
    int cnt = 0;
    if (res.next()) cnt = res.getInt(1);
%>
<h2>게시물 목록</h2>
<p>총 <%= cnt %>개의 게시물이 있습니다.</p>
<table>
    <colgroup>
        <col width="10%">
        <col width="15%">
        <col width="60%">
        <col width="15%">
    </colgroup>
    <thead>
        <tr>
            <th>번호</th>
            <th>작성자</th>
            <th>제목</th>
            <th>작성일</th>
        </tr>
    </thead>
    <tbody>
        <%
            /* 회원정보 list 가져오기 */
            sql = "SELECT * from sys.board order by reg_date asc";
            res = conn.prepareStatement(sql).executeQuery();
            String idx, writer, subject, reg_date, link;
            while (res.next()) {
                idx = res.getString("idx");
                writer = res.getString("writer");
                subject = res.getString("subject");
                reg_date = res.getString("reg_date");
                link = "./view.jsp?idx="+idx;
                
                /** 
                 *  년-월-일 시간:분 형태로 가져옴
                 *  input  : 2018-07-29 00:00:00
                 *  output : 2018-07-29 00:00
                 */
                if(reg_date.length() > 16) reg_date = reg_date.substring(0,16);
        %>
        <tr style="text-align:center;">
            <td><%= idx %></td>
            <td><%= writer %></td>
            <td><a href="<%= link %>"><%= subject %></a></td>
            <td><%= reg_date %></td>
        </tr>
        <%
            }
        %>
    </tbody>
</table>
<div class="btn_group right">
    <button type="button" onclick="location.href = './write.jsp'">작성</button>
</div>
<%@ include file="footer.jsp" %>

index.jsp는 게시물의 목록을 조회하는 페이지입니다. tr을 반복하는 구문에서 조회 페이지로 이동할 수 있도록 링크를 만들어줍니다.

그리고 하단에는 작성 페이지로 이동할 수 있는 버튼을 만들어서 다른 페이지와 상호작용을 해야 합니다.

자세한 내용은 주석을 확인해주세요.

 

5. write.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="header.jsp" %>
<div>
    <form action="./action.jsp" method="post">
        <fieldset><legend>게시물 작성</legend>
            <input type="hidden" name="action" value="board_insert">
            <ul>
                <li>
                    <label>
                        <span>작성자 :</span>
                        <input type="text" name="writer" size="20" required>
                    </label>
                </li>
                <li>
                    <label>
                        <span>제목 :</span>
                        <input type="text" name="subject" size="20" required>
                    </label>
                </li>
                <li>
                    <label>
                        <span>내용 :</span>
                        <textarea name="content" cols="80" rows="5" required></textarea>
                    </label>
                </li>
            </ul>
            <div class="btn_group">
                <button type="button" onclick="history.back(); return false;">취소</button>
                <button type="submit">전송</button>
            </div>
        </fieldset>
    </form>
</div>
<%@ include file="footer.jsp" %>

form을 작성 후 전송하면 action.jsp에서 일괄적으로 처리합니다. 이 때 name="action"에서 지정한 값을 통하여 driven 할 수 있도록 작성할 것입니다.

 

6. view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="header.jsp" %>
<%
    /* next value 가져오기 */
    String idx = request.getParameter("idx");
    String writer, subject, content, reg_date;
    ResultSet res;
    sql = "SELECT * from sys.board where idx = "+idx;
    res = conn.prepareStatement(sql).executeQuery();
    res.next();
    writer = res.getString("writer");
    subject = res.getString("subject");
    content = res.getString("content");
    reg_date = res.getString("reg_date");
%>
<h2>게시물 조회</h2>
<ul>
    <li>글번호 : <%= idx %></li>
    <li>작성자 : <%= writer %></li>
    <li>제목 : <%= subject %></li>
    <li>작성일 : <%= reg_date %></li>
    <li>내용 : <%= content %></li>
</ul>
<%
    sql = "SELECT * FROM sys.comment_list where bidx = "+idx+" order by idx desc";
    res = conn.prepareStatement(sql).executeQuery();
%>
<h2>댓글 조회</h2>
<ul>
    <%
    int cnt = 0;
    String comment_idx, comment_writer, comment_content, comment_reg_date;
    while (res.next()) {
        cnt++;
        comment_idx = res.getString("idx");
        comment_writer = res.getString("writer");
        comment_content = res.getString("content");
        comment_reg_date = res.getString("reg_date");
    %>
    <li>
        <%= comment_writer %> /
        <%= comment_content %> /
        <%= comment_reg_date %> /
        <a href="./comment_delete.jsp?idx=<%= comment_idx %>" onclick="if(!confirm('정말로 삭제하시겠습니까?')) return false;">삭제</a></li>
    <% } %>
</ul>
<div>
    <form action="./action.jsp?idx=<%= idx %>" method="post">
        <fieldset><legend>댓글작성</legend>
            <input type="hidden" name="action" value="comment_insert">
            <input type="text" name="writer" size="10" placeholder="작성자">
            <input type="text" name="content" size="80" placeholder="내용">
            <button type="submit">작성완료</button>
        </fieldset>
    </form>
</div>
<div>
    <button type="button" onclick="history.back(); return false;">목록</button>
    <button type="button" onclick="location.href = './update.jsp?idx=<%= idx %>'">수정</button>
    <button type="button" onclick="if(!confirm('정말로 삭제하시겠습니까?')) return false; location.href = './delete.jsp?idx=<%= idx %>'">삭제</button>
</div>
<%@ include file="footer.jsp" %>

view.jsp에서 댓글 목록이 보여져야 합니다. 그리고 댓글을 작성할 수 있어야 합니다.

댓글도 마찬가지로 action.jsp에서 처리하도록 합니다. 이 때 파라미터(parameter)의 idx에 게시물 번호를 넘겨줍니다. 여기서 사용되는 idx는 comment에서 bidx에 삽입 될 것입니다. bidx는 게시물 번호를 의미합니다.

 

7. update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="header.jsp" %>
<%
    /* next value 가져오기 */
    String idx = request.getParameter("idx");
    String writer, subject, content, reg_date;
    ResultSet res;
    sql = "SELECT * from sys.board where idx = "+idx;
    res = conn.prepareStatement(sql).executeQuery();
    res.next();
    writer = res.getString("writer");
    subject = res.getString("subject");
    content = res.getString("content");
%>
<div>
    <form action="./action.jsp?idx=<%= idx %>" method="post">
        <fieldset><legend>게시물 작성</legend>
            <input type="hidden" name="action" value="board_update">
            <ul>
                <li>
                    <label>
                        <span>작성자 :</span>
                        <input type="text" name="writer" value="<%= writer %>" size="20" required>
                    </label>
                </li>
                <li>
                    <label>
                        <span>제목 :</span>
                        <input type="text" name="subject" value="<%= subject %>" size="20" required>
                    </label>
                </li>
                <li>
                    <label>
                        <span>내용 :</span>
                        <textarea name="content" cols="80" rows="5" required><%= content %></textarea>
                    </label>
                </li>
            </ul>
            <div class="btn_group">
                <button type="button" onclick="history.back(); return false;">취소</button>
                <button type="submit">전송</button>
            </div>
        </fieldset>
    </form>
</div>
<%@ include file="footer.jsp" %>

update.jsp는 write.jsp와 view.jsp를 합친것이라고 생각하면 됩니다. view.jsp 처럼 게시물의 정보를 불러오고, write.jsp의 폼 형태에 해당 값을 넣어줌으로써 게시물의 원본 데이터를 수정하기 전에 보여지도록 할 수 있습니다.

 

8. action.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="dbConnection.jsp" %>
<%
    String action = request.getParameter("action");
    PreparedStatement pstmt = null;
    
    /**
     * index.jsp, view.jsp update.jsp에서 form을 전송할 때
     * action을 hidden값으로 전송한다. 해당 값에 맞는 명령을 수행하도록  작성 
     */
    switch (action) {
    case "board_insert" :
        sql = "INSERT INTO sys.board values(sys.board_seq.nextval, ?, ?, ?, SYSDATE)";
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, request.getParameter("writer"));
        pstmt.setString(2, request.getParameter("subject"));
        pstmt.setString(3, request.getParameter("content"));
        break;
    case "comment_insert" :
        sql = "INSERT INTO sys.comment_list values(sys.comment_seq.nextval, ?, ?, ?, SYSDATE)";
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, request.getParameter("idx"));
        pstmt.setString(2, request.getParameter("writer"));
        pstmt.setString(3, request.getParameter("content"));
        break;
    case "board_update" :
        sql  = "update sys.board SET writer = ?, subject = ?, content = ? where idx = ?";
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, request.getParameter("writer"));
        pstmt.setString(2, request.getParameter("subject"));
        pstmt.setString(3, request.getParameter("content"));
        pstmt.setString(4, request.getParameter("idx"));
        break;
    }
    //out.println(sql.trim());
    //if(true) return;
    pstmt.executeQuery();
%>
<script>
    alert('완료되었습니다.');
    location.replace('./');
</script>

action.jsp에서 모든 form 전송을 처리합니다.

처리 완료 후 script 부분에서 페이지 이동을 담당합니다.

 

9. delete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="dbConnection.jsp" %>
<%
    String idx = request.getParameter("idx");
    sql = "DELETE FROM sys.board where idx = "+idx;
    conn.prepareStatement(sql).executeUpdate();
%>
<script>
    alert('완료되었습니다.');
    location.replace('./');
</script>

delete는 따로 form을 전송할 필요 없이 바로 실행해주면 됩니다. 여기에서 게시물 삭제를 담당합니다.

 

10. comment_delete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="dbConnection.jsp" %>
<%
    PreparedStatement pstmt = null;

    String idx = request.getParameter("idx");
    sql = "DELETE FROM sys.comment_list where idx = "+idx;
    conn.prepareStatement(sql).executeQuery();
%>
<script>
    alert('완료되었습니다.');
    location.replace('./')
</script>

comment_delete에서 댓글 삭제를 담당합니다.