🔥 게시판 전체 조회 전 기본 설정 🔥
💻 Board VO 클래스 구성 (lombok 활용)
package com.kh.spring.board.model.vo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@Setter
@Getter
@ToString
public class Board {
private int boardNo; // BOARD_NO NUMBER
private String boardTitle; // BOARD_TITLE VARCHAR2(100 BYTE)
private String boardWriter; // BOARD_WRITER VARCHAR2(4000 BYTE)
private String boardContent; // BOARD_CONTENT VARCHAR2(4000 BYTE)
private String originName; // ORIGIN_NAME VARCHAR2(100 BYTE)
private String changeName; // CHANGE_NAME VARCHAR2(100 BYTE)
private int count; // COUNT NUMBER
private String createDate; // CREATE_DATE DATE
private String status; // STATUS VARCHAR2(1 BYTE)
}
💻 BoardService 인터페이스 구성
package com.kh.spring.board.model.service;
import java.util.ArrayList;
import com.kh.spring.board.model.vo.Board;
import com.kh.spring.board.model.vo.Reply;
import com.kh.spring.common.model.vo.PageInfo;
public interface BoardService {
// 게시글 리스트 조회 서비스 + 페이징 처리
// 게시글의 총 갯수
int selectListCount();
// 게시글 리스트 조회
ArrayList<Board> selectList(PageInfo pi);
// 게시글 상세 조회 서비스
// 게시글 조회 수 증가
int increaseCount(int boardNo);
// 게시글 상세 조회 요청
Board selectBoard(int boardNo);
// 게시글 작성 서비스
int insertBoard(Board b);
// 게시글 삭제 서비스
int deleteBoard(int boardNo);
// 게시글 수정 서비스
int updateBoard(int boardNo);
// 댓글 리스트 조회용 서비스(Ajax)
int insertReply(Reply r);
}
💻 BoardServiceImpl (@Service) 클래스 구성
package com.kh.spring.board.model.service;
import java.util.ArrayList;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kh.spring.board.model.dao.BoardDao;
import com.kh.spring.board.model.vo.Board;
import com.kh.spring.board.model.vo.Reply;
import com.kh.spring.common.model.vo.PageInfo;
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDao boardDao;
@Autowired
private SqlSession sqlSession;
@Override
public int selectListCount() {
return 0;
}
@Override
public ArrayList<Board> selectList(PageInfo pi) {
return null;
}
@Override
public int increaseCount(int boardNo) {
return 0;
}
@Override
public Board selectBoard(int boardNo) {
return null;
}
@Override
public int insertBoard(Board b) {
return 0;
}
@Override
public int deleteBoard(int boardNo) {
return 0;
}
@Override
public int updateBoard(int boardNo) {
return 0;
}
@Override
public int insertReply(Reply r) {
return 0;
}
}
💻 BoardDao (@Repository) 클래스 구성
package com.kh.spring.board.model.dao;
import org.springframework.stereotype.Repository;
@Repository
public class BoardDao {
}
💻 BoardController 생성 (@Controller)
package com.kh.spring.board.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.kh.spring.board.model.service.BoardService;
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
}
🙋🏻♀️ taglib 지시어를 미리 포함된 상태로 JSP파일을 만들 수는 없나요?
🙆🏻♀️ 당연히 됩니다!
💻 header.jsp
👉🏻 자유게시판 링크 달기
<div id="header_2">
<ul>
<li><a href="">HOME</a></li>
<li><a href="">공지사항</a></li>
<li><a href="list.bo">자유게시판</a></li>
<li><a href="">사진게시판</a></li>
</ul>
</div>
💻 boardListView 생성
👉🏻 제공 폼 붙여넣기👉🏻 style 중 기본 스타일과 겹치는 .content, .innerOuter 제외 후 붙여 넣기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#boardList {text-align:center;}
#boardList>tbody>tr:hover {cursor:pointer;}
#pagingArea {width:fit-content; margin:auto;}
#searchForm {
width:80%;
margin:auto;
}
#searchForm>* {
float:left;
margin:5px;
}
.select {width:20%;}
.text {width:53%;}
.searchBtn {width:20%;}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp" />
<div class="content">
<br><br>
<div class="innerOuter" style="padding:5% 10%;">
<h2>게시판</h2>
<br>
<!-- 로그인 후 상태일 경우만 보여지는 글쓰기 버튼 -->
<a class="btn btn-secondary" style="float:right;" href="">글쓰기</a>
<br>
<br>
<table id="boardList" class="table table-hover" align="center">
<thead>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
<th>첨부파일</th>
</tr>
</thead>
<tbody>
<tr>
<td>5</td>
<td>마지막 공지사항제목</td>
<td>admin</td>
<td>10</td>
<td>2020-02-10</td>
<td>★</td>
</tr>
<tr>
<td>4</td>
<td>네번째 공지사항제목</td>
<td>admin</td>
<td>10</td>
<td>2020-02-07</td>
<td>★</td>
</tr>
<tr>
<td>3</td>
<td>세번째 공지사항제목</td>
<td>admin</td>
<td>10</td>
<td>2020-02-03</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td>두번째 공지사항제목</td>
<td>admin</td>
<td>100</td>
<td>2020-02-01</td>
<td></td>
</tr>
<tr>
<td>1</td>
<td>첫번째 공지사항제목</td>
<td>admin</td>
<td>45</td>
<td>2019-12-25</td>
<td>★</td>
</tr>
</tbody>
</table>
<br>
<div id="pagingArea">
<ul class="pagination">
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">4</a></li>
<li class="page-item"><a class="page-link" href="#">5</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</div>
<br clear="both"><br>
<form id="searchForm" action="" method="get" align="center">
<div class="select">
<select class="custom-select" name="condition">
<option value="writer">작성자</option>
<option value="title">제목</option>
<option value="content">내용</option>
</select>
</div>
<div class="text">
<input type="text" class="form-control" name="keyword">
</div>
<button type="submit" class="searchBtn btn btn-secondary">검색</button>
</form>
<br><br>
</div>
<br><br>
</div>
<jsp:include page="../common/footer.jsp" />
</body>
</html>
🔥 게시판 전체 조회 🔥
⌨️ defaultValue를 적용하지 않은 BoardController
package com.kh.spring.board.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.kh.spring.board.model.service.BoardService;
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
// 메뉴바 클릭 시 => list.bo (기본적으로 1번 페이지 요청)
// 페이징바 클릭 시 => list.bo?cpage=요청하는페이지수
@RequestMapping("list.bo")
public String selectList(@RequestParam(value="cpage") int currentPage) {
System.out.println("cpage: " + currentPage);
// /WEB-INF/views/board/boardListView.jsp
return "board/boardListView";
}
}
📍 현재 쿼리스트링이 없는 경우 400 에러가 뜸!
(쿼리스트링으로 cpage=숫자 값을 붙여 주면 잘 뜸)
💻 defaultValue를 설정한 BoardController
👉🏻 값이 넘어오지 않았다면 대체할 값으로 1을 줌(defaultValue 설정)
👉🏻 url에 default값이 노출되지는 않지만 400 에러가 더 이상 뜨지 않음! (상용 웹사이트도 이런 식으로 디폴트 값을 설정해 줌)
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
// 메뉴바 클릭 시 => list.bo (기본적으로 1번 페이지 요청)
// 페이징바 클릭 시 => list.bo?cpage=요청하는페이지수
@RequestMapping("list.bo")
public String selectList(@RequestParam(value="cpage", defaultValue="1") int currentPage) {
// System.out.println("cpage: " + currentPage);
int listCount = boardService.selectListCount();
// /WEB-INF/views/board/boardListView.jsp
return "board/boardListView";
}
💻 BoardServiceImpl
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDao boardDao;
@Autowired
private SqlSessionTemplate sqlSession;
@Override
public int selectListCount() {
return boardDao.selectListCount(sqlSession);
}
}
💻 BoardDao
@Repository
public class BoardDao {
public int selectListCount(SqlSessionTemplate sqlSession) {
// 완성된 쿼리문이므로 두 번째 매개변수는 필요 없음
return sqlSession.selectOne("boardMapper.selectListCount");
}
💻 board-mapper.xml
<select id="selectListCount" resultType="_int">
SELECT COUNT(*)
FROM BOARD
WHERE STATUS = 'Y'
</select>
🔥 페이징 처리 - 전체 조회(상단) 코드가 선행되어야 함 🔥
💻 BoardController
package com.kh.spring.board.controller;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.kh.spring.board.model.service.BoardService;
import com.kh.spring.board.model.vo.Board;
import com.kh.spring.common.model.vo.PageInfo;
import com.kh.spring.common.template.Pagination;
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
// 메뉴바 클릭 시 => list.bo (기본적으로 1번 페이지 요청)
// 페이징바 클릭 시 => list.bo?cpage=요청하는페이지수
@RequestMapping("list.bo")
public String selectList(@RequestParam(value="cpage", defaultValue="1") int currentPage, Model model) {
// System.out.println("cpage: " + currentPage);
int listCount = boardService.selectListCount();
int pageLimit = 10;
int boardLimit = 5;
PageInfo pi = Pagination.getPageInfo(listCount, currentPage, pageLimit, boardLimit);
ArrayList<Board> list = boardService.selectList(pi);
model.addAttribute("pi", pi);
model.addAttribute("list", list);
// /WEB-INF/views/board/boardListView.jsp
return "board/boardListView";
}
}
💻 BoardServiceImpl
@Override
public ArrayList<Board> selectList(PageInfo pi) {
return boardDao.selectList(sqlSession, pi);
}
💻 BoardDao
public ArrayList<Board> selectList(SqlSessionTemplate sqlSession, PageInfo pi) {
int limit = pi.getBoardLimit();
int offset = (pi.getCurrentPage() - 1) * limit;
RowBounds rowBounds = new RowBounds(offset, limit);
return (ArrayList)sqlSession.selectList("boardMapper.selectList", null, rowBounds);
}
💻 board-mapper.xml
<resultMap id="boardResultSet" type="board">
<result column="BOARD_NO" property="boardNo" />
<result column="BOARD_TITLE" property="boardTitle" />
<result column="BOARD_WRITER" property="boardWriter" />
<result column="COUNT" property="count" />
<result column="CREATE_DATE" property="createDate" />
<result column="ORIGIN_NAME" property="originName" />
</resultMap>
<select id="selectList">
SELECT BOARD_NO
, BOARD_TITLE
, BOARD_WRITER
, COUNT
, TO_CHAR(CREATE_DATE, 'YYYY-MM-DD') AS "CREATE_DATE"
, ORIGIN_NAME
FROM BOARD
WHERE STATUS = 'Y'
ORDER BY BOARD_NO DESC
</select>
💻 boardListView 동적 코딩 ver.
👉🏻 로그인 전후 글쓰기 버튼 활성화/비활성화
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#boardList {text-align:center;}
#boardList>tbody>tr:hover {cursor:pointer;}
#pagingArea {width:fit-content; margin:auto;}
#searchForm {
width:80%;
margin:auto;
}
#searchForm>* {
float:left;
margin:5px;
}
.select {width:20%;}
.text {width:53%;}
.searchBtn {width:20%;}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp" />
<div class="content">
<br><br>
<div class="innerOuter" style="padding:5% 10%;">
<h2>게시판</h2>
<br>
<!-- 로그인 후 상태일 경우만 보여지는 글쓰기 버튼 -->
<c:if test="${ not empty loginUser }">
<a class="btn btn-secondary" style="float:right;" href="enrollForm.bo">글쓰기</a>
</c:if>
<br>
<br>
<table id="boardList" class="table table-hover" align="center">
<thead>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
<th>첨부파일</th>
</tr>
</thead>
<tbody>
<c:forEach var="b" items="${ list }">
<tr>
<td>${ b.boardNo }</td>
<td>${ b.boardTitle }<td>
<td>${ b.boardWriter }</td>
<td>${ b.count }</td>
<td>${ b.createDate }</td>
<td>
<c:if test="${ not empty b.originName }">
★
</c:if>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<br>
<div id="pagingArea">
<ul class="pagination">
<c:choose>
<c:when test="${ pi.currentPage eq 1 }">
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="list.bo?cpage=${ pi.currentPage - 1 }">Previous</a></li>
</c:otherwise>
</c:choose>
<c:forEach var="p" begin="${ pi.startPage }" end="${ pi.endPage }" step="1">
<li class="page-item"><a class="page-link" href="list.bo?cpage=${ p }">${ p }</a></li>
</c:forEach>
<c:choose>
<c:when test="${ pi.currentPage eq pi.maxPage }">
<li class="page-item disabled"><a class="page-link" href="#">Next</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="list.bo?cpage=${ pi.currentPage + 1 }">Next</a></li>
</c:otherwise>
</c:choose>
</ul>
</div>
<br clear="both"><br>
<form id="searchForm" action="" method="get" align="center">
<div class="select">
<select class="custom-select" name="condition">
<option value="writer">작성자</option>
<option value="title">제목</option>
<option value="content">내용</option>
</select>
</div>
<div class="text">
<input type="text" class="form-control" name="keyword">
</div>
<button type="submit" class="searchBtn btn btn-secondary">검색</button>
</form>
<br><br>
</div>
<br><br>
</div>
<jsp:include page="../common/footer.jsp" />
</body>
</html>
더보기
👉🏻 로그인 안 했을 때는 글쓰기 버튼이 없음
👉🏻 1page 일 때는 Previous disabled 속성 걸려 있음
👉🏻 2page, 3page 쭉쭉 가다 보면
👉🏻 마지막 Page에서 Next 버튼 막힘