19.05.08 JSP 게시판 - 시스템 구조 및 게시판 만들기 (~동영상 43강)

Back-End/JSP 2019. 5. 8. 22:15

 

-게시판의 구조 (글읽기 옆에 답변형 추가됨)-



-테이블 구조(총 11개의 컬럼을 만들어 데이터를 저장)-

글 그룹 : 글을 묶어놓은 그룹

글 스텝 : 글의 단계 (ex - 글의 답변의 답변, 글의 답변 같은 단계별로 넘어가는 글)

글 레벨 : 글을 보여주는 순서 (ex-최신순서대로 보여줄지.)


컬럼명

설명

비고

Num 

글번호

자동증가 int

Writer

글쓴이 

String 

Email

이메일 

String 

Subject

글제목 

String 

Password

글 비밀번호 

String 

Reg_date

글 작성날짜 

Date 

Ref

글 그룹 

Int 

Re_step

글 스텝

Int 

Re_level

글 레벨 

Int 

Readcount

조회수 

Int 

Content 

글내용 

String 



예시)


글번호

글제목

ref

Re_step 

Re_level 

베스킨라빈스 

1

1

[re] 난 나뚜르

1

2

3

            [re] 나뚜르 나도 

1

3

4

   [re] 베스킨좋아 

1

2

2



실제 작성시 정렬되는 순서

글번호

글제목

ref

Re_step 

Re_level 

1

베스킨라빈스 

1

1

           [re]베스킨좋아

           [re]난 나뚜르 

               [re] 나뚜르 나도


 

[게시글 쓰기] 작성 순서


글쓰기 > 글쓰기 처리 > 글쓰기 저장 > 전체게시글 보기

 

 


-예제 및 출력 결과-

 

(글쓰기 저장까지 구현됨)

글쓰기 (BoardWriteForm.jsp) --> 글쓰기처리 (BoardWriteProc.jsp) --> 글쓰기 저장 (BoardDAO) --> 전체게시글 보기 (BoardList.jsp)


1.데이터베이스 테이블, 시퀀스 (게시판관련된 숫자를 자동으로 생성하기 위해) 만들기

 

 

 

 

 

 

2. server.xml파일 수정 (커넥션풀 사용할수있도록) - (마지막부분)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
 
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>
 
      <Context docBase="ch11" path="/ch11" reloadable="true" source="org.eclipse.jst.jee.server:ch11"/><Context docBase="ch14" path="/ch14" reloadable="true" source="org.eclipse.jst.jee.server:ch14"/><Context docBase="Board" path="/Board" reloadable="true" source="org.eclipse.jst.jee.server:Board">
          <Resource auth = "Container" driverClassName = "oracle.jdbc.driver.OracleDriver" loginTimeout = "10" maxWait = "5000" name = "jdbc/pool" password = "123456" type = "javax.sql.DataSource" url = "jdbc:oracle:thin:@localhost:1521:xe" username = "system"/> 
      </Context>//데이터베이스를 사용하기 위한 커넥션 풀 코드 추가 및 수정, 바로 위쪽 줄 (org.eclipse.jst.jee.server:Board"/> /제거
      </Host>
    </Engine>
  </Service>
</Server>
cs




3. 페이지 작성

 

BoardWriteForm.jsp (회원가입)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<center>
<h2> 게시글 쓰기 </h2> 
 
<form action="BoardWriteProc.jsp" method="post">
<table width = "600" border="1" bordercolor = "gray" bgcolor = "skyblue"> <!-- bordercolor는 선색깔 지정 -->
    <tr height = "40">
        <td align = "center" width = "150"> 작성자 </td> <!-- ref는 데이터베이스에서 처리하기 때문에 따로 받지 않는다. -->
        <td width = "450"> <input type = "text" name = "writer" size = "60"></td> 
    </tr>
    
    <tr height = "40">
        <td align = "center" width = "150"> 제목 </td>
        <td width = "450"> <input type = "text" name = "subject" size = "60"></td>
    </tr>
    
    <tr height = "40">
        <td align = "center" width = "150"> 이메일 </td>
        <td width = "450"> <input type = "text" name = "email" size = "60"></td>
    </tr>
    
    <tr height = "40">
        <td align = "center" width = "150"> 비밀번호 </td>
        <td width = "450"> <input type = "password" name = "password" size = "61"></td>
    </tr>
    
    <tr height = "40">
        <td align = "center" width = "150"> 글내용 </td>
        <td width = "450"><textarea rows = "10" cols = "50" name = "content"></textarea></td>
    </tr>
    
    <tr height = "40">
        <td align = "center" colspan = "2">
            <input type = "submit" value = "글쓰기"> &nbsp;&nbsp;
            <input type = "reset" value = "다시작성"> &nbsp;&nbsp;
            <button onclick = "location.href='BoardList.jsp'">전체 게시글 보기</button> <!-- 클릭하면 BoardList.jsp페이지로 넘어가는 버튼-->
        </td>
    </tr>
</table>
</form>
</center>
</body>
</html>
 
cs

 

 

BoardWriteProc.jsp (회원가입 처리)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<%@page import="model.BoardDAO"%>
<%@page import="model.BoardBean"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
 
    <% 
    request.setCharacterEncoding("EUC-KR"); //한글깨짐 방지 문자셋 설정
%>
    <!-- 빈파일에서 게시글 작성한 데이터를 한번에 읽어들임 -->
    <!-- use빈을 사용하여 자바빈을 사용, id는 빈클래스를 지칭하는 참조 변수명 -->
    <!-- 빈파일에 있는 값들을 받는다. -->
    <!-- 빈파일에 없는 값들은 null로 들어온다 null값으로 들어온 것들은 데이터베이스에서 들어올 값들이니 걱정x -->
 
    <jsp:useBean id="boardbean" class="model.BoardBean">
        <jsp:setProperty name="boardbean" property="*" />
    </jsp:useBean>
 
    <%
    //데이터베이스 쪽으로 빈클래스를 넘겨줌
    BoardDAO bdao = new BoardDAO();
    
    //데이터 저장 메소드를 호출
    bdao.insertBoard(boardbean);
 
%>
 
 
 
 
</body>
</html>
 
cs

 

 

BoardDAO.java (데이터베이스 연동)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package model;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.naming.Context;
 
public class BoardDAO {
 
    // 데이터베이스에 연결하기 위한 설정
    Connection con;
    PreparedStatement pstmt;
    ResultSet rs;
 
    // 데이터베이스의 커넥션풀들을 사용하도록 설정하는 메소드
    public void getCon() {
 
        try { // 데이터베이스에 접속할때는 예외처리를 해주어야한다.
 
            Context initctx = new InitialContext(); // 외부에서 데이터를 읽어들어야 하기 때문에 Context 객체 생성
            // 톰캣 서버에 정보를 담아놓은 곳으로 이동함
            Context envctx = (Context) initctx.lookup("java:comp/env"); // lookup메소드를 이용해서 자료를 읽어오는 코드
            DataSource ds = (DataSource) envctx.lookup("jdbc/pool"); // datasource 객체를 선언 , 오브젝트 타입이기 때문에 타입변환을 한다.

           

            //Resource 이름을 매개값으로 주어 DataResource 객체를 리턴
   
            //외부에서 데이터를 읽어들이는 Context 객체를 생성
            //그 객체의 lookup 메소드로 톰캣서버 정보를 읽어들이고
            //톰캣 서버정보를 읽어들인 객체의 lookup 메소드 리소스이름을 매개값으로 주어
            //데이터소스객체 (커넥션풀 사용할때 쓰기로한 객체)를 얻는다.
            //(커넥션풀)데이터소스를 이용하여 접속

            

 
            con = ds.getConnection(); // 데이터 소스를 기준으로 커넥션을 연결함
        } catch (Exception e) {
            e.printStackTrace(); // 어느부분이 잘못되었는지 알려주는 예외처리
        }
    }
 
    // 하나의 새로운 게시글이 넘어와서 저장되는 메소드
    public void insertBoard(BoardBean bean) {
        getCon();
        // 빈클래스에 넘어오지 않았던 데이터들을 초기화 해주어야 한다.
 
        int ref = 0// 글그룹을 의미한다, 쿼리를 실행시켜서 가장 큰 ref값을 가져온후 +1을 더해주면 된다.
        int re_step = 1// 새글이고, 부모글은 글 스텝(Re_step), 글 레벨(Re_level)은 1이기 때문에 초기값을 1을 준다.
        int re_level = 1// 새글이고, 부모글은 글 스텝(Re_step), 글 레벨(Re_level)은 1이기 때문에 초기값을 1을 준다.
 
        try {
 
            // 가장큰 ref값을 읽어오는 쿼리 준비함 (새로운 글은 ref가 가장크기 때문)
            String refsql = "select max(ref) from board"// board테이블로부터 가장큰 ref를 검색
            // 쿼리를 실행할 객체
            pstmt = con.prepareStatement(refsql);
            // 쿼리 실행후 결과를 리턴
            rs = pstmt.executeQuery();
            if (rs.next()) { // 쿼리(rs)가 결과값이 있다면 실행하는 구문
                ref = rs.getInt(1+ 1// 최대값에 1을 더해서 글그룹을 설정. 새로운글은 ref숫자가 하나씩 올라가야 하기 때문
            }
 
            // 실제로 게시글 전체값을 테이블에 저장
            String sql = "insert into board values(board_seq.NEXTVAL,?,?,?,?,sysdate,?,?,?,0,?)"// ?가 아니라 시퀀스를 사용해
                                                                                                    // 시퀀스에 이미 들어가있는값의
                                                                                                    // 다음값을 자동으로 매핑해서
                                                                                                    // 넣어준다.
            pstmt = con.prepareStatement(sql);
            // ?에 값을 매핑한다. //0은 카운트값이기때문 0을 넣어주었다
            pstmt.setString(1, bean.getWriter());
            pstmt.setString(2, bean.getEmail());
            pstmt.setString(3, bean.getSubject());
            pstmt.setString(4, bean.getPassword());
            pstmt.setInt(5, ref);
            pstmt.setInt(6, re_step);
            pstmt.setInt(7, re_level);
            pstmt.setString(8, bean.getContent());
 
            // 쿼리를 실행하시오.
            pstmt.executeUpdate();
            // 자원 반납
            con.close();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 
cs

 

 

BoardBean.java (빈클래스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package model;
 
public class BoardBean { //빈클래스 생성
    
    private int num;
    private String email;
    private String subject;
    private String password;
    private String reg_date;
    private String writer;
    private int ref;
    private int re_step;
    private int re_lever;
    private int readcount;
    private String content;
    
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getReg_date() {
        return reg_date;
    }
    public void setReg_date(String reg_date) {
        this.reg_date = reg_date;
    }
    public String getWriter() {
        return writer;
    }
    public void setWriter(String writer) {
        this.writer = writer;
    }
    public int getRef() {
        return ref;
    }
    public void setRef(int ref) {
        this.ref = ref;
    }
    public int getRe_step() {
        return re_step;
    }
    public void setRe_step(int re_step) {
        this.re_step = re_step;
    }
    public int getRe_lever() {
        return re_lever;
    }
    public void setRe_lever(int re_lever) {
        this.re_lever = re_lever;
    }
    public int getReadcount() {
        return readcount;
    }
    public void setReadcount(int readcount) {
        this.readcount = readcount;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    
}
 
cs

 

 

: