-- 헤더, 푸터 나눔
(근데 헤더 왜 안 들가농,,, 중복 변수?)
<게시판>
😱
더보기
1. Board 클래스 생성
package com.insertcoin.board.model.vo;
import java.sql.Date;
public class Board {
// 필드부
private int genNo; // GEN_NO NUMBER PRIMARY KEY,
private String genCategory; // GEN_CATEGORY VARCHAR2(10) NOT NULL,
private int gameNo; // GAME_NO NUMBER REFERENCES GAME(GAME_NO),
private String memNo; // MEM_NO NUMBER NOT NULL REFERENCES MEMBER(MEM_NO),
private String genTitle; // GEN_TITLE VARCHAR2(100) NOT NULL,
private String genContent; // GEN_CONTENT VARCHAR2(4000) NOT NULL,
private Date genRegister; // GEN_REGISTER_DATE DATE DEFAULT SYSDATE NOT NULL,
private int genViews; // GEN_VIEWS NUMBER DEFAULT 0,
private String genShow; // GEN_SHOW CHAR(1) DEFAULT 'Y' NOT NULL);
// 생성자부
public Board() {
super();
}
public Board(int genNo, String genCategory, int gameNo, String memNo, String genTitle, String genContent,
Date genRegister, int genViews, String genShow) {
super();
this.genNo = genNo;
this.genCategory = genCategory;
this.gameNo = gameNo;
this.memNo = memNo;
this.genTitle = genTitle;
this.genContent = genContent;
this.genRegister = genRegister;
this.genViews = genViews;
this.genShow = genShow;
}
// 게시글 메인용 생성자
public Board(int genNo, String genCategory, int gameNo, String memNo, String genTitle, Date genRegister,
int genViews) {
super();
this.genNo = genNo;
this.genCategory = genCategory;
this.gameNo = gameNo;
this.memNo = memNo;
this.genTitle = genTitle;
this.genRegister = genRegister;
this.genViews = genViews;
}
// 메소드부
public int getGenNo() {
return genNo;
}
public void setGenNo(int genNo) {
this.genNo = genNo;
}
public String getGenCategory() {
return genCategory;
}
public void setGenCategory(String genCategory) {
this.genCategory = genCategory;
}
public int getGameNo() {
return gameNo;
}
public void setGameNo(int gameNo) {
this.gameNo = gameNo;
}
public String getMemNo() {
return memNo;
}
public void setMemNo(String memNo) {
this.memNo = memNo;
}
public String getGenTitle() {
return genTitle;
}
public void setGenTitle(String genTitle) {
this.genTitle = genTitle;
}
public String getGenContent() {
return genContent;
}
public void setGenContent(String genContent) {
this.genContent = genContent;
}
public Date getGenRegister() {
return genRegister;
}
public void setGenRegister(Date genRegister) {
this.genRegister = genRegister;
}
public int getGenViews() {
return genViews;
}
public void setGenViews(int genViews) {
this.genViews = genViews;
}
public String getGenShow() {
return genShow;
}
public void setGenShow(String genShow) {
this.genShow = genShow;
}
@Override
public String toString() {
return "Board [genNo=" + genNo + ", genCategory=" + genCategory + ", gameNo=" + gameNo + ", memNo=" + memNo
+ ", genTitle=" + genTitle + ", genContent=" + genContent + ", genRegister=" + genRegister
+ ", genViews=" + genViews + ", genShow=" + genShow + "]";
}
}
2. boardListView.jsp - 게시판 메인 폼 - 하드코딩 ver
(하드 코딩으로 기본 폼 구축 후 controller-service-dao 다녀와서 동적 코딩으로 바꿔 주기)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>자유게시판 메인</title>
<!-- CSS 스타일시트 -->
<link href="boardListView.css" rel="stylesheet">
<!-- jQuery 라이브러리 연결 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<!-- Bootstrap 프레임워크 연결 -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<!-- Popper JS -->
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<!-- 컨텐츠 영역 -->
<div class="content_container">
<div class="outer">
<div id="title">자유게시판</div>
<!-- 조회할 게시물이 보여질 자리 -->
<table align="center" class="list-area">
<thead>
<tr id="board_title">
<!-- th[width=]*6 + Enter -->
<th width="100">글번호</th>
<th width="100">카테고리</th>
<th width="700">제목</th>
<th width="150">작성자</th>
<th width="70">조회수</th>
<th width="150">작성일</th>
</tr>
</thead>
<tbody>
<tr class="line">
<td>15</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>14</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>13</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>12</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>11</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>10</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>9</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>8</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>7</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>6</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>5</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>4</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>3</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>2</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
<tr class="line">
<td>1</td>
<td>게임</td>
<td>게시글 제목이다</td>
<td>user02</td>
<td>10</td>
<td>2022-05-01</td>
</tr>
</tbody>
</table>
<br>
<div class="board_search board_left">
<input type="button" value="글쓰기" class="board_button">
</div>
<div class="board_search board-right">
<select class="board_search">
<option selected>제목+내용</option>
<option value="10">제목</option>
<option value="20">내용</option>
<option value="30">작성자</option>
<option value="40">댓글</option>
<option value="50">게임명</option>
</select>
<input type="text">
<button class="board_button">검색</button>
</div>
<br><br>
<!-- 페이징바 -->
<div align="center" class="paging-area">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button>10</button>
</div>
</div>
</div>
</body>
</html>
3. mainLogin.jsp - 링크 연결
<ul>
<li><a href=""> 개발자 게시판</a></li>
<li><a onclick="genBoardPage();"> 자유 게시판</a></li>
</ul>
<script>
function genBoardPage() {
location.href= "<%= contextPath %>/list.bo?currentPage=1";
}
</script>
4. PageInfo 클래스 생성
package com.insertcoin.common.model.vo;
public class PageInfo {
// 필드부
private int listCount; // 현재 총 게시글 개수
private int currentPage; // 현재 요청한 페이지
private int pageLimit; // 페이지 하단에 보여질 페이징 바의 최대 개수
private int boardLimit; // 한 페이지에 보여질 게시글의 최대 개수
private int maxPage; // 가장 마지막 페이지 수
private int startPage; // 페이지 하단에 보여질 페이징 바의 시작 수
private int endPage; // 페이지 하단에 보여질 페이징 바의 끝 수
// 생성자부
public PageInfo() { }
public PageInfo(int listCount, int currentPage, int pageLimit, int boardLimit, int maxPage, int startPage,
int endPage) {
super();
this.listCount = listCount;
this.currentPage = currentPage;
this.pageLimit = pageLimit;
this.boardLimit = boardLimit;
this.maxPage = maxPage;
this.startPage = startPage;
this.endPage = endPage;
}
// 메소드부
public int getListCount() {
return listCount;
}
public void setListCount(int listCount) {
this.listCount = listCount;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageLimit() {
return pageLimit;
}
public void setPageLimit(int pageLimit) {
this.pageLimit = pageLimit;
}
public int getBoardLimit() {
return boardLimit;
}
public void setBoardLimit(int boardLimit) {
this.boardLimit = boardLimit;
}
public int getMaxPage() {
return maxPage;
}
public void setMaxPage(int maxPage) {
this.maxPage = maxPage;
}
public int getStartPage() {
return startPage;
}
public void setStartPage(int startPage) {
this.startPage = startPage;
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int endPage) {
this.endPage = endPage;
}
@Override
public String toString() {
return "PageInfo [listCount=" + listCount + ", currentPage=" + currentPage + ", pageLimit=" + pageLimit
+ ", boardLimit=" + boardLimit + ", maxPage=" + maxPage + ", startPage=" + startPage + ", endPage="
+ endPage + "]";
}
}
5. BoardListController - URL mapping: /list.bo
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 페이징 처리
int listCount; // 현재 총 게시글 개수
int currentPage; // 현재 요청한 페이지(= 사용자 요청 페이지)
int pageLimit; // 10개 == 페이지 하단에 보여질 페이징 바의 페이지 최대 개수
int boardLimit; // 10개 == 한 페이지에 보여질 게시글 최대 개수
int maxPage; // 가장 마지막 페이지가 몇 번 페이지인지
int startPage; // 페이지 하단에 보여질 페이징바의 시작 수(1, 11, ...)
int endPage; // 페이지 하단에 보여질 페이징바의 끝 수(10, 20, ...)
// 총 게시글 개수
listCount = new BoardService().selectListCount();
// 현재 페이지
currentPage = Integer.parseInt(request.getParameter("currentPage"));
// 하단에 보여질 페이징 바와 한 페이지의 게시글의 최대 개수
pageLimit = 10;
boardLimit = 10;
// 가장 마지막 페이지는 몇 번 페이지?
// => (게시글 / 10)에 대한 값을 무조건 올림
maxPage = (int)Math.ceil((double)listCount / boardLimit);
// 페이지 하단에 보일 페이징바의 시작수 (1, 11, ...)
startPage = (currentPage - 1) / pageLimit * pageLimit +1;
// 페이지 하단에 보여질 페이징바의 끝수 (10, 20, ...)
endPage = startPage + pageLimit - 1;
if(endPage > maxPage) {
endPage = maxPage;
} // 만약 게시글의 총합이 10 단위로 떨어지지 않는 수라면, maxPage를 페이징바의 끝수로
// pageInfo 객체로 가공
PageInfo pi = new PageInfo(listCount, currentPage, pageLimit, boardLimit
, maxPage, startPage, endPage);
// pi를 서비스로 넘기기
// list에는 해당 페이지에서 보여져야 할 게시글의 목록들
ArrayList<Board> list = new BoardService().selectList(pi);
request.setAttribute("pi", pi);
request.setAttribute("list", list);
request.getRequestDispatcher("views/board/boardListView.jsp").forward(request, response);
}
6. BoardService
package com.insertcoin.board.model.service;
import java.sql.Connection;
import java.util.ArrayList;
import com.insertcoin.board.model.dao.BoardDao;
import com.insertcoin.board.model.vo.Board;
import com.insertcoin.common.model.vo.PageInfo;
import static com.insertcoin.common.JDBCTemplate.*;
public class BoardService {
public int selectListCount() {
Connection conn = getConnection();
int listCount = new BoardDao().selectListCount(conn);
close(conn);
return listCount;
}
public ArrayList<Board> selectList(PageInfo pi) {
Connection conn = getConnection();
ArrayList<Board> list = new BoardDao().selectList(conn, pi);
close(conn);
return list;
}
}
7. BoardDao
package com.insertcoin.board.model.dao;
import static com.insertcoin.common.JDBCTemplate.close;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;
import com.insertcoin.board.model.vo.Board;
import com.insertcoin.common.model.vo.PageInfo;
public class BoardDao {
private Properties prop = new Properties();
public BoardDao() {
String fileName = BoardDao.class.getResource("/sql/board/board-mapper.xml").getPath();
try {
prop.loadFromXML(new FileInputStream(fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
public int selectListCount(Connection conn) {
// SELECT문 => ResultSet 객체
int listCount = 0;
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectListCount");
try {
pstmt = conn.prepareStatement(sql);
rset = pstmt.executeQuery();
// 1행 조회하므로 while 쓸 필요 없이 if로 가능!
if(rset.next()) {
listCount = rset.getInt("COUNT");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return listCount;
}
public ArrayList<Board> selectList(Connection conn, PageInfo pi) {
// SELECT문 => ResultSet 객체 (여러 행 조회)
ArrayList<Board> list = new ArrayList<>();
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectList");
try {
pstmt = conn.prepareStatement(sql);
int startRow = (pi.getCurrentPage() - 1) * pi.getBoardLimit() + 1;
int endRow = startRow + pi.getBoardLimit() -1;
pstmt.setInt(1, startRow);
pstmt.setInt(2, endRow);
rset = pstmt.executeQuery();
while(rset.next()) {
list.add(new Board(rset.getInt("GEN_NO")
, rset.getString("GEN_CATEGORY")
, rset.getInt("GAME_NO")
, rset.getString("MEM_NICKNAME")
, rset.getString("GEN_TITLE")
, rset.getDate("GEN_REGISTER_DATE")
, rset.getInt("GEN_VIEWS")));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return list;
}
}
8. board-mapper.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>SQL</comment>
<entry key="selectListCount">
SELECT COUNT(*) COUNT
FROM GEN_BOARD
WHERE GEN_SHOW = 'Y'
</entry>
<entry key="selectList">
SELECT *
FROM (SELECT ROWNUM RNUM, A.*
FROM (SELECT GEN_NO
, GEN_CATEGORY
, B.GAME_NO
, M.MEM_NICKNAME
, GEN_TITLE
, GEN_REGISTER_DATE
, GEN_VIEWS
FROM GEN_BOARD B
LEFT OUTER JOIN GAME G ON (B.GAME_NO = G.GAME_NO)
JOIN MEMBER M ON (B.MEM_NO = M.MEM_NO)
WHERE GEN_SHOW = 'Y'
ORDER BY GEN_NO DESC) A)
WHERE RNUM BETWEEN ? AND ?
</entry>
</properties>
9. boardListView.jsp 동적 코딩 ver
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.insertcoin.common.model.vo.PageInfo, java.util.ArrayList, com.insertcoin.board.model.vo.Board" %>
<%
// 필요한 데이터 뽑기
PageInfo pi = (PageInfo)request.getAttribute("pi"); // 페이징바 만들기
ArrayList<Board> list = (ArrayList<Board>)request.getAttribute("list"); // 조회된 내용물 출력
int currentPage = pi.getCurrentPage();
int startPage = pi.getStartPage();
int endPage = pi.getEndPage();
int maxPage = pi.getMaxPage();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>자유게시판 메인</title>
<!-- CSS 스타일시트 -->
<link href="resources/css/boardListView.css" rel="stylesheet">
<!-- jQuery 라이브러리 연결 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<!-- Bootstrap 프레임워크 연결 -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<!-- Popper JS -->
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<!-- 전체 영역 -->
<div class="wrap">
<%@ include file = "../../views/common/header.jsp" %>
<div class="outer">
<!-- 컨텐츠 영역 -->
<div class="content_container">
<div class="outer">
<div id="title">자유게시판</div>
<!-- 조회할 게시물이 보여질 자리 -->
<table align="center" class="list-area">
<thead>
<tr id="board_title">
<!-- th[width=]*6 + Enter -->
<th width="100">글번호</th>
<th width="100">카테고리</th>
<th width="700">제목</th>
<th width="150">작성자</th>
<th width="70">조회수</th>
<th width="150">작성일</th>
</tr>
</thead>
<tbody>
<% if(list.isEmpty()) { %>
<tr>
<td colspan="6">조회된 리스트가 없습니다.</td>
</tr>
<% } else { %>
<% for(Board b : list) { %>
<tr class="line">
<td><%= b.getGenNo() %></td>
<td><%= b.getGenCategory() %></td>
<td><%= b.getGenTitle() %></td>
<td><%= b.getMemNo() %></td>
<td><%= b.getGenViews() %></td>
<td><%= b.getGenRegister() %></td>
</tr>
<% } %>
<% } %>
</tbody>
</table>
<br>
<% if(loginUser != null) { %>
<div class="board_search board_left">
<input type="button" value="글쓰기" class="board_button" onclick="enrollPage();">
</div>
<% } %>
<div class="board_search board-right">
<select class="board_search">
<option selected>제목+내용</option>
<option value="10">제목</option>
<option value="20">내용</option>
<option value="30">작성자</option>
<option value="40">댓글</option>
<option value="50">게임명</option>
</select>
<input type="text">
<button class="board_button">검색</button>
</div>
<br><br>
<!-- 페이징바 -->
<button onclick="location.href='<%= contextPath%>/list.bo?currentPage=<%= currentPage -1 %>';"><</button>
<% for(int p = startPage; p <= endPage; p++) { %>
<% if(p != currentPage) { %>
<button onclick="location.href='<%= contextPath %>/list.bo?currentPage=<%= p %>';"><%= p %></button>
<% } else { %> <!-- 현재 내가 보고 있는 페이지는 클릭 안 되게 -->
<button disabled><%= p %></button>
<% } %>
<% } %>
<% if(currentPage != maxPage) { %>
<button onclick="location.href='<%= contextPath%>/list.bo?currentPage=<%= currentPage +1 %>';">></button>
<% } %>
</div>
</div>
</div>
<%@ include file = "../../views/common/footer.jsp" %>
</div>
<script>
function enrollPage() {
location.href = "<%=contextPath %>/enrollForm.bo";
}
// 게시글에 클릭 버튼 걸기
$(function() {
$(".list-area>tbody>tr").click(function() {
location.href = "<%= contextPath %>/detail.bo?bno=" + $(this).children().eq(0).text();
});
});
</script>
</body>
</html>
😱 완료된 소분류
확인할 부분
더보기
ㅇ
<대분류2>
😱 소분류1
😱 소분류2
더보기
ㅇ