본문 바로가기
JDBC/JSP-SERVLET

[JSP] Q&A 게시판 만들기 1(Question)

by 썬키 2022. 1. 26.

https://itsmesunky.tistory.com/35

 

JDBC - 자바와 데이터베이스 연동하기(2)

JDBC란? JDBC 순서 Web Project 생성, 라이브러리 추가 DB 연결하기 VO 클래스 만들기 Service 클래스 만들기 DAO 클래스 만들기 JDBC - 자바와 데이터베이스 연동하기(1) JDBC란? JDBC 순서 Web Project 생성, 라..

itsmesunky.tistory.com

 

앞전에 포스팅했던 글을 참고하면 JDBC가 어떤 원리, 구조로 작동되는지 알 수 있다.

사실, 일부분만 포스팅하고 나머지 부분은 아직까지 포스팅을 못했는데 차차 해보도록 하겠다.

 

오늘은 QNA 게시판을 만들어 보려고 한다.

게시판 짜는건 코드만 조금씩 다를 뿐이지 비슷비슷해서 한 번 익혀놓으면 잘 할 수 있다고 생각한다.

 

우선, 게시판 하나를 만들기 위해서는

라이브러리, DB 파일, VO 파일, SERVICE 파일, DAO 파일, JSP 파일이 필요하다.

 

그 외, 사이트를 꾸미기 위해서 필터, 사이트메쉬 필요한 파일이나 소스가 많겠지만

기본 기능을 구현하기 위해서는 위에 언급했던 파일로도 충분하다.

 

 

JSP 파일목록
패키지 목록

 

밑에 나와있는 순서대로만 보고 코드를 작성한다면,

어떤 게시판이든 만들기가 가능하니 잘 따라서 해보길 바란다. (따라하실 분들은)

 

 

QNA 테이블의 객체 목록

package com.webjjang.qna.vo;

public class QnaVO {

	private long no;
	private String title, content, id, name, writeDate;
	private long hit, refNo;
	private int ordNo, levNo;
	private long parentNo;
	public long getNo() {
		return no;
	}
	public void setNo(long no) {
		this.no = no;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getWriteDate() {
		return writeDate;
	}
	public void setWriteDate(String writeDate) {
		this.writeDate = writeDate;
	}
	public long getHit() {
		return hit;
	}
	public void setHit(long hit) {
		this.hit = hit;
	}
	public long getRefNo() {
		return refNo;
	}
	public void setRefNo(long refNo) {
		this.refNo = refNo;
	}
	public int getOrdNo() {
		return ordNo;
	}
	public void setOrdNo(int ordNo) {
		this.ordNo = ordNo;
	}
	public int getLevNo() {
		return levNo;
	}
	public void setLevNo(int levNo) {
		this.levNo = levNo;
	}
	public long getParentNo() {
		return parentNo;
	}
	public void setParentNo(long parentNo) {
		this.parentNo = parentNo;
	}
	@Override
	public String toString() {
		return "QnaVO [no=" + no + ", title=" + title + ", content=" + content + ", id=" + id + ", name=" + name
				+ ", writeDate=" + writeDate + ", hit=" + hit + ", refNo=" + refNo + ", ordNo=" + ordNo + ", levNo="
				+ levNo + ", parentNo=" + parentNo + "]";
	}
}

1. VO 객체 생성

데이터베이스를 통해 만들어 놓은 객체들을 참고해 VO 객체를 생성한다.

 

 

package com.webjjang.qna.service;

import java.util.List;

import com.webjjang.qna.dao.QnaDAO;
import com.webjjang.qna.vo.QnaVO;
import com.webjjang.util.PageObject;

public class QnaListSerivce {

	public List<QnaVO> service(PageObject pageObject) throws Exception{
		//DB 처리 객체 생성
		QnaDAO dao = new QnaDAO();
		//페이지 처리로 전체 데이터 개수를 가져와서 pageObject에 넣어준다.
		pageObject.setTotalRow(dao.getTotalRow(pageObject));
		//리스트 데이터를 가져와서 리턴한다.
		return dao.list(pageObject);
		
	}
}

2. SERVICE 패키지에 LIST SERVICE 패키지 만들기

페이지처리를 하기 위해서 서비스 메서드에 PageObject를 넣고 setTotalRow 메서드를 이용하였다.

(페이지 처리를 하기 위해서는 라이브러리가 필요하니 따라하실 분들은 댓글을 남겨주세요!

 

 

package com.webjjang.qna.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.webjjang.qna.vo.QnaVO;
import com.webjjang.util.PageObject;
import com.webjjang.util.db.DB;

public class QnaDAO {
	
	//필요한 객체 선언 - 전역 변수(:모든 메서드에서 사용가능)
	//연결 객체
	Connection con = null;
	//실행 객체
	PreparedStatement ppsm = null;
	//결과 저장 객체
	ResultSet rs = null;
	
	//1. 질문 답변 리스트 데이터 가져오는 메서드 선언
	public List<QnaVO> list(PageObject pageObject)throws Exception{
		//실행 위치와 전달 데이터 확인
		System.out.println("QnaDAO.list().pageObject : " + pageObject);
		//리턴 데이터 변수 선언
		List<QnaVO> list = null;
		
		//데이터 채우기 - DB에서 가져오므로 예외처리를 해야한다.
		try { //정상 처리
			//1. 드라이버 확인 → DB.java에서 static 초기화 블록으로 해결
			//2. 연결 가져온다.
			con = DB.getConnection();
			//3. 실행할 SQL문 작성
			//-1. 원본 데이터 가져오기
			String sql = " select q.no, q.title, q.id, m.name, q.writeDate, q.hit, q.refNo, q.ordNo, q.levNo, q.parentNo "
					+ " from qna q, member m "
					+ " where m.id = q.id "
					+ " order by q.refNo desc, q.ordNo ";
			//-2. 순서 번호 부여
			sql = " select rownum rnum, no, title, id, name, writeDate, hit, "
					+ " refNo, ordNo, levNo, parentNo FROM( " + sql + ")";
			//-3. 페이지에 맞는 데이터 가져오기
			sql = " select rnum, no, title, id, name, writeDate, hit, "
					+ " refNo, ordNo, levNo, parentNo FROM( " + sql + ") "
							+ " WHERE rnum between ? and ?";
			System.out.println("QnaDAO.list().sql : " + sql);
			//4. 실행 객체 & 데이터 세팅
			ppsm = con.prepareStatement(sql);
			//startRow, endRow의 계산은 setTotalRow()를 호출해야만 나온다.
			//그렇지 않으면 0이 돼서 데이터가 나오지 않는다.
			ppsm.setLong(1,pageObject.getStartRow());
			ppsm.setLong(2,pageObject.getEndRow());
			//5. 실행 결과
			rs = ppsm.executeQuery();
			//6. 데이터 담기
			if(rs != null) {
				//리스트 데이터는 여러개이다. 반복문 사용해야 한다.
				//rs.next() → 다음 포인터로 이동시킨다. 맨 처음 포인터는 -1이다.
				//데이터가 있으면 true가 리턴된다.
				while(rs.next()) {
					//list가 null이면 데이터를 담을수 없으므로 생성해준다.
					//└한번만 처리할수 있도록 if문 처리해준다.
					if(list == null) list = new ArrayList<QnaVO>();
					//데이터 한개를 담기 위한 vo 생성
					QnaVO vo = new QnaVO();
					//setter를 이용해서 rs에서 가져온 데이터 담기
					vo.setNo(rs.getLong("no"));
					vo.setTitle(rs.getString("title"));
					vo.setId(rs.getString("id"));
					vo.setName(rs.getString("name"));
					vo.setWriteDate(rs.getString("writeDate"));
					vo.setHit(rs.getLong("hit"));
					vo.setRefNo(rs.getLong("refNo"));
					vo.setOrdNo(rs.getInt("ordNo"));
					vo.setLevNo(rs.getInt("levNo"));
					vo.setParentNo(rs.getLong("parentNo"));
					
					//list 객체에 데이터가 담긴 vo 객체를 넣는다.
					list.add(vo);
				} //while문의 끝
				} //if문의 끝
		} catch (Exception e) {
			// TODO: handle exception
			// 개발자를 위해서 오류 경로 추적 출력
			e.printStackTrace();
		}finally { //반드시 처리 - 닫기
			try {
				//7. 사용 객체 닫기
				DB.close(con, ppsm, rs);
			} catch (Exception e) {
				// TODO: handle exception
				// 개발자를 위해서 오류 경로 추적 출력
				e.printStackTrace();
			}
		}
		//수집한 데이터를 넘긴다.
		return list;
}

3. DAO에 LIST 메서드 작성하기

위에 첨부했던 링크를 참고하면 게시판 만들 때 필요한 객체 3가지가 있음을 알 수 있다.

차례대로 선언하고 코드를 이어서 작성한다.

코드마다 한 줄 주석을 작성해 놓았으니 따라하실 분들은 참고하세요!

 

 

<%@page import="com.webjjang.qna.vo.QnaVO"%>
<%@page import="com.webjjang.util.PageObject"%>
<%@page import="com.opensymphony.module.sitemesh.Page"%>
<%@page import="java.util.List"%>
<%@page import="com.webjjang.qna.service.QnaListSerivce"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ taglib prefix="pageNav" tagdir="/WEB-INF/tags" %>
 <%
//자바 부분입니다.

//넘어오는 페이지 정보를 받아서 페이지 객체 생성
PageObject pageObject = PageObject.getInstance(request);

//리스트 데이터를 가져오기 위한 객체 생성
QnaListSerivce service = new QnaListSerivce();
List<QnaVO> list = service.service(pageObject);

//EL 객체나 JSTL 객체로 사용하기 위해 기본 저장 객체(request)에 담는다.
//EL 라이브러리는 톰캣에 포함되어 있다. JSTL을 별도로 다운 받아서 /WEB-INF/lib에 넣어 두셔야 합니다.
request.setAttribute("list", list);
request.setAttribute("pageObject", pageObject);
 %> 
<!DOCTYPE html>
<html>
<!-- head : html의 설정 → sitemesh에서는 적용이 안되는 부분의 주석 -->
<head>
<meta charset="UTF-8">
<title>질문답변</title>
<style type="text/css">
.dataRow:hover{
	background: #eee;
	cursor: pointer;
}
</style>
<script type="text/javascript">
$(function(){
	$(".dataRow").click(function(){
// 		alert("데이터 클릭");
		// .data("no") → body 태그 안에 data-no 속성으로 데이터가 저장되어 있는 것을 가져온다.
		var no = $(this).data("no");
// 		alert(no);
		location = "view.jsp?no=" + no + "&inc=1";
	});
});
</script>
</head>
<!-- body : 데이터가 표시되는 부분 → sitemesh에서는 적용이 안되는 부분의 주석 -->
<body>
<div class="container">
<h2>질문/답변</h2>
<!-- 테이블에 데이터 표시 -->
<table class="table">
	<!-- 제목 줄 표시 -->
	<tr>
		<th>번호</th>
		<th>제목</th>
		<th>작성자</th>
		<th>작성일</th>
		<th>조회수</th>
	</tr>
	<!-- 데이터가 있는 만큼 JSTL의 반복문을 이용해서 tr을 만들어서 표시. 한 개의 데이터를 vo에 담는다. -->
	<c:forEach items="${list }" var="vo">
	<!-- 데이터 한 줄 정의 : class="dataRow", 글 번호를 tr태그 안에 data-no로 숨겨둔다. -->
	<tr class="dataRow" data-no="${vo.no }">
		<td>${vo.no }</td>
		<td>
			<!-- 들여쓰기 levNo를 이용해서 공백문자 표시 3칸 적용. &nbsp; 공백문자 -->
			<!--  begin : 시작 숫자, end : 끝 숫자 -->
			<c:forEach begin="1" end="${vo.levNo * 2 }">
				&nbsp;
			</c:forEach>
			<!--  답변글 기호 표시 -->
			<c:if test="${vo.levNo > 0 }">
				<i class="material-icons">&#xe5da;</i>
			</c:if>
			${vo.title }
		</td>
		<td>${vo.name }(${vo.id })</td>
		<td>${vo.writeDate }</td>
		<td>${vo.hit }</td>
	</tr>
	</c:forEach>
	<tr>
		<td colspan="5" align="center">
			<pageNav:pageNav listURI="list.jsp" pageObject="${pageObject }"/>
		</td>
	</tr>
	<!-- 로그인을 한 경우 질문하기 버튼이 보인다. -->
	<c:if test="${!empty login }">
	<tr>
		<td colspan="5" align="right">
			<a href="writeForm.jsp" class="btn btn-primary">질문하기</a>
		</td>
	</tr>
	</c:if>
</table>
</div>
</body>
</html>

4. JSP 폴더에 list.jsp 파일 만들기

EL 객체와 JSTL 객체를 사용했기 때문에  코드도 그에 맞게 사용했다.

 

 

이영환은 학원 강사님 성함인데, 이 자리를 빌어 초상권? 암튼 성함 쓰게 되었습니다.. 감사 인사?를 드립니다

잘 따라했다면 이렇게 리스트가 출력되는것을 볼 수 있다.

 

 

 

나머지 view, write, update, delete 관련 코드들이

필요한 사람들이 있으면 공유하겠습니다!

 

 

 

'JDBC > JSP-SERVLET' 카테고리의 다른 글

[JSP] JSP에 값을 넘겨주는 여러가지 방법  (0) 2023.01.31
[JSP] 메인페이지 만들기  (0) 2022.01.28

댓글