Spring
회원가입, 로그인, 게시판 백엔드 실습( 게시판 리스트 )
hojomu
2023. 4. 5. 15:23
데이터 베이스에 저장되어있는 데이터를 게시판에 나타내자.
1. Controller
// 게시판 메인
@RequestMapping(value="/board/list", method = RequestMethod.GET)
public String list (Model model, CriteriaVO cri) {
model.addAttribute("list", bs.list(cri));
int total=bs.total(cri);
model.addAttribute("paging", new PageVO(cri, total));
return "board/list";
}
- bs.list() 함수의 결과로 게시글에 대한 정보를 ArrayList에 담아오고
- bs.total() 의 결과로 게시글의 총 량을 int 타입으로 받아올 것이다.
- 게시판을 나타내기 위해서 총 2가지 모델이 필요하다.
먼저, 페이지 넘버, 전체 게시글 양, 검색 키워드, 게시글 타입을 저장할 수 있는
CriteriaVO
public class CriteriaVO {
private int pageNum;
private int amount;
private String keyword;
private String type;
//생성자
public CriteriaVO() {
this(1,10);
}
public CriteriaVO(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
필드에 대한 getter, getter
}
두 번째는, 페이지네이션을 작성하기 위해
시작 페이지, 끝 페이지, 이전, 다음, CriteriaVO , total 데이터를 담을 수 있는
BoardVO
public class PageVO {
private int startPage;
private int endPage;
private boolean prev;
private boolean next;
private CriteriaVO cri;
private int total;
public PageVO(CriteriaVO cri, int total) {
this.cri = cri;
this.total = total;
//끝 번호 식 : 현재 페이지 / 10(올림) * 10
this.endPage = (int)(Math.ceil(cri.getPageNum() / 10.0)) * 10;
// 시작번호 식 : 끝 번호 - 9
this.startPage = this.endPage - 9;
// 제일 마지막 페이지 번호는 전체 건수를 고려해야한다.
// 제일 마짐가 끝 번호 식 : 전체 건수(올림) / 페이지당 게시물 갯수
// 123 * 1.0 = 123.0(올림) / 10 ==> 130/10 = 13
int realEnd = (int)(Math.ceil((total * 1.0)/cri.getAmount()));
// 13(real End) < 20(endPage) 면
// realEnd가 적용되게 함.
if(realEnd < this.endPage) {
this.endPage = realEnd;
}
// startPage가 1보다 크면 이전 버튼 활성화
this.prev = this.startPage > 1;
// endPage가 realEnd 보다 작으면
this.next = this.endPage < realEnd;
필드에 대한 getter, setter
}
- 이 두 model은 현제 게시판의 위치를 기준으로 필요한 게시글 데이터를 가져올 것이다.
2. Service, ServiceImpl
public interface BoardService {
// 게시판 전체 불러오기
public ArrayList<BoardVO> list(CriteriaVO cri);
// 테이블의 전체 건수 불러오기
public int total(CriteriaVO cri);
@Service
public class BoardServiceImpl implements BoardService{
@Autowired
BoardMapper bm;
// 글 전체 내용 (테이블 전체) 불러오기
public ArrayList<BoardVO> list(CriteriaVO cri){
return bm.list(cri);
}
// 전체 글 건수 불러오기
public int total(CriteriaVO cri) {
return bm.total(cri);
}
- 각각 list와 total로 부터 불러올 값에 대한 데이터를 알맞게 설정해야한다.
3. Mapper , Mapper.xml
public interface BoardMapper {
// 게시글 정보, 전체 개시글의 갯수 불러오기
public ArrayList<BoardVO> list(CriteriaVO cri);
public int total(CriteriaVO cri);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="hjm.portfolio.mapper.BoardMapper">
<select id="list" resultType="hjm.portfolio.model.BoardVO">
select *
from(
select @rownum:=@rownum+1 rownum, b.*
from port_board b,
(select @rownum:=0) as tmp
order by board_no desc
) as boardlist
</select>
</mapper>
** keyword에 따라 다르게 나타내는 기능은 아직 구현하지 않음
- Mapper.xml에서 변수 @rownum을 정의하고, 0으로 초기화했다. 이후 Select 문에서는 @rownum 변수를 1씩 증가시키면서, 각 행에 대한 일렬번호와 함께 모든 열을 조회함으로서,
각 행이 일련번호를 부여하고, board_no 열을 기준으로 내림차순으로 데이터를 조회한다.
** tmp : @rownum 변수를 초기화 하는 용도로 사용되는 일시적인 테이블
4. jsp
<table id="datatablesSimple" style="width:80%">
<thead>
<tr>
<th style="width:10%" >글번호</th>
<th style="width:40%">제목</th>
<th style="width:10%">작성자</th>
<th style="width:15%">작성일</th>
<th style="width:10%">조회</th>
<th style="width:10%">좋아요</th>
</tr>
</thead>
<tbody>
<!-- for문 시작 -->
<c:forEach items="${list}" var="boardlist">
<tr>
<td>${boardlist.board_no}</td>
<td><a href="/board/detail?board_no=${boardlist.board_no}">${boardlist.title}</a></td>
<td>${boardlist.id}</td>
<td>${boardlist.updated_time}</td>
<td>${boardlist.counts}</td>
<td>${boardlist.likes}</td>
</tr>
</c:forEach>
<!-- for문 끝 -->
</tbody>
</table>
<!-- prev(이전)이 true이면 이전버튼 활성화 -->
<c:if test="${paging.prev}">
<a href="/board/list?type=${paging.cri.type}&keyword=${paging.cri.keyword}&pageNum=${paging.startPage-1}&amount=${paging.cri.amount}">이전</a>
</c:if>
<!-- begin(1)이 end(10)될 동안 반복(1일 10일 될 동안 반복) -->
<c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="num">
<a href="/board/list?type=${paging.cri.type}&keyword=${paging.cri.keyword}&pageNum=${num}&amount=${paging.cri.amount}">${num}</a>
</c:forEach>
<!-- next(다음)이 true이면 다음버튼 활성화 -->
<c:if test="${paging.next}">
<a href="/board/list?type=${paging.cri.type}&keyword=${paging.cri.keyword}&pageNum=${paging.endPage+1}&amount=${paging.cri.amount}">다음</a>
</c:if>
- 데이터 베이스에 저장된 게시글을 10개씩 나눠서 나타낸다.