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개씩 나눠서 나타낸다.