Community_게시판

DeadWhale·2022년 5월 23일
0

Servlet/JSP

목록 보기
14/22
post-thumbnail

개빡셨다 뭔가 다 헷갈렸다 ㅋㅋ

pagination(페이지 구분)

Step.1 : HTML/CSS

세미로 만드는 부분에서 크게 별다른 부분은 차이가 나지않았지만
pagination 부분은 진짜 헷갈렸다.


하나의 section안에 div 3개와 form태그 하나로 구성햇다.


게시판 테이블을 감싸는 'list-wrapper' div객체
게시글 작성을 위한 작성 버튼을 감싼 'btn-area' div객체
pagination을 나누기 위한 ul을 감싸는 'pagination-area' div
( 보통 pagination을 나눌때는 주로 list을 사용한다고 함)
+ 검색를 하기 위한 form 태그

css에서 기억할만한 것

  • table중에서 사용되는 td에는 고유한 border가 있는데. 이 테두리가 테이블을 개 못생기게 한다.이러한 고유 border를 지워버리는 옵션을 사용하면 예뻐진다.


Step.2 : Servlet

@WebServlet("/board/list") --게시판에서 요청되는 웹상 주소
public class BoardListServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
        
        --type : 게시판의 종류를 읽어온다. 1:공지 2:자유
        --queryString Parameter는 무조건 String 자료형이라 int형 parse필요
  		 int type = Integer.parseInt(req.getParameter("type"));

		--nav 메뉴선택시 queryString에 cp가 없으면 1으로 고정	
        --cp( Current Page )현재 페이지 별다른 요청이 없으면 1으로 고정
		int cp = 1;
		
        --페이지네이션의 번호 선택 시 
		--쿼리스트링에 cp가 있음 --> cp = 쿼리스트링의 cp 값
		if(req.getParameter("cp") !=null){
				cp =Integer.parseInt(req.getParameter("cp"));}			

		
       BoardService service = new BoardService();

		--매개값으로'현재게시판 번호','현재 페이지 수'를 전달한다.
		--게시판 이름, 페이지네이션 객체, 게시글 리스트 3개를 한번에 반환하는 service 호출
		Map<String, Object> map = service.selectBoardList(type,cp);

			--request범위로 map을 세팅
			req.setAttribute("map", map);

			--요청위임할 주소저장하고 dispatcher로 요청전달
			String path = "/WEB-INF/views/board/boardList.jsp";
			RequestDispatcher dispatcher = req.getRequestDispatcher(path);

			dispatcher.forward(req, resp);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Step.3 : Service

순차적으로 진행한다

1. 매개변수로 전달 받은 type값으로 dao 수행해 어느 게시판인지 확인.

String boardName = dao.selectBoardName(conn,type);

2-1. 요청받은 게시판의 전체 게시글 조회

int listCount = dao.selectListCount(conn,type);

1번에서 board_type 테이블에서 게시판의 이름을 조회해 해당 게시판에 있는 모든 게시글의 수를 측정한다.
DAO 수행문도 게시판의 이름을 알아내는거랑 거의 동일하다

2-2. 전체 게시글수+현재페이지를 이용해 Pagination객체 생성

2-1에서 요청받은 게시판에 잇는 모든 게시글의 수를 확인했고
cp 매개변수에는 요청부터 전달된 현재 페이지의 값이 들어있다
이 두개의 정보를 가지고 페이징(한쪽한쪽분할 하는거)

Pagination pagination = new Pagination(cp, listCount);
public class Pagination {
	//페이징 처리 : 1쪽 2쪽 한 페이지를 나눈다는 의미 
	//페이지네이션 : 페이징 처리에 필요한 모든 값을 저장하고 있는 객체

	private int currentPage; //현재 페이지 번호
	private int listCount;  //모든 게시글 수

	private int limit = 10; //한 페이지에 보여질 게시글의 수
	private int pageSize =10;  // 목록 하단에 페이즈번호의 노출 개수.

	private int maxPage;     //제일 큰 페이지 번호 == 50페이지.
	private int startPage;   //목록 하단에 노출된 페이지의 시작번호
	private int endPage;     //목록 하단에 노출된 페이지의 끝번호

	private int prevPage;    //목록 하단된 노출된 번호의 이전 목록 끝 번호
	private int nextPage; 	 //목록 하단된 노출된 번호의 시작 목록 시작 번호

	public Pagination(int currentPage,int listCount) {
		this.currentPage = currentPage;
		this.listCount = listCount;
		calculatePagination(); //자동으로 계산하게 메서드 호출
	}

객체가 생성될 때(new) 기본생성자가 생성되지 않고 매개변수생성자만 수행될 수 있다.

입력받은 현재 페이지와 모든게시글의 수를 전달받아
나머지 계산하는 함수를 호출해 필요한 데이터들을 계산해 대입한다.

calculatePagination( )

// 페이징 처리에 필요한 값을 계산하는 메서드
	private void calculatePagination() {

		// * maxPage 계산 : 최대 페이지 수 == 마지막 페이지 번호

		// 전체 게시글 수 : 500개 // 보여지는 게시글 수: 10개
		// -> 마지막 페이지 번호는? 500 / 10 = 50

		// 전체 게시글 수 : 501개 // 보여지는 게시글 수: 10개
		// -> 마지막 페이지 번호는? 501 / 10 = 51 (50.1의 올림 처리)

		maxPage = (int) Math.ceil((double) listCount / limit);

		// * startPage : 목록 하단에 노출된 페이지의 시작 번호

		// 목록 하단 페이지 번호의 노출 개수가 10개일 때

		// 현재 페이지가 1~10 인 경우 : 1
		// 현재 페이지가 11~20 인 경우 : 11
		// 현재 페이지가 21~30 인 경우 : 21

		startPage = (currentPage - 1) / pageSize * pageSize + 1;

		// * endPage : 목록 하단에 노출된 페이지의 끝 번호

		// 목록 하단 페이지 번호의 노출 개수가 10개일 때

		// 현재 페이지가 1~10 인 경우 : 10
		// 현재 페이지가 11~20 인 경우 : 20
		// 현재 페이지가 21~30 인 경우 : 30

		endPage = startPage + pageSize - 1;

		// 만약에 endPage가 maxPage를 초과하는 경우
		if (endPage > maxPage) {
			endPage = maxPage;
		}

		// * prevPage(<) : 목록 하단에 노출된 번호의 이전 목록 끝 번호
		// * nextPage(>) : 목록 하단에 노출된 번호의 다음 목록 시작 번호

		// 현재 페이지가 1~10 일 경우
		// < : 1 페이지
		// > : 11 페이지

		// 현재 페이지가 11~20 일 경우
		// < : 10 페이지
		// > : 21 페이지

		// 현재 페이지가 41~50 일 경우 (maxPage가 50)
		// < : 40 페이지
		// > : 50 페이지

		if (currentPage <= pageSize) {
			prevPage = 1;
		} else {
			prevPage = startPage - 1;
		}

		if (endPage == maxPage) {
			nextPage = maxPage;
		} else {
			nextPage = endPage + 1;
		}

	}

넘 헷갈렸다 ㅋㅋㅋ 실질적인 코드는 적은데 엄청 헷갈린다.


lombok를 사용하지 하지 않고 그냥 추가했는데 이유는


현재페이지,
모든게시글의수,
한페이지에 보여질 게시글의 수,
목록하단에 위치한 페이지번호의 노출 갯수


에 변화가 있을때 다시 계산할 필요성이 있어 위 4개의 값에 setter가 수행하면
calculatePagination()함수를 호출한다.

3. 요청받은 게시판의 전체 게시글 조회

현재페이지를 기준으로해 해당 페이지의 게시글 목록을 가져온다
게시글은 여러개이다 보니 list형태로 가져와야한다.
이때 매개변수로 Connection + 생성한Pagination + type

List<Board> boardList = dao.selectBoardList(conn,pagination,type);

DAO 수행구문은 그냥 평범하지만 게시글 목록에 첫글과 마지막 글을 지정하는 구문이 필요하다 이게 좀 헷갈린다.

int start = (pagination.getCurrentPage()-1)*pagination.getLimit()+1;
int end = start+pagination.getLimit()-1;

시작

  • (현재페이지-1)*한페이지 보일 최대 게시글 수+1
    ex) 1페이지 : 1-10 번 게시글들이 보여야함
  1. (1-1)*10+1
  2. 0*10+1
  3. 0+1
    [1페이지부터 시작하게 됨]

  • 시작페이지+한페이지에 보일 최대 게시글-1;
  1. 1+10-1;
  2. 11 - 1;
    [10페이지까지 끝나게 됨]


    이런 로직이 수행된다.

SQL

이렇게 수행되는 SQL문이 복잡하다
3개의 SELECT문으로 구성되어 있다.

1. 게시글번호+게시글제목+닉네임+작성일+조회수를 조회하는 SELECT

  • 보통 게시글은 최신순부터 게시글을 정렬해서 100,99,98,97 이런형태로 정렬된다
  1. 이렇게 반대로 정렬된 SELECT에서 ROWNUM을 이용해 순서를 대입한다
  • 게시글번호를 반대로 정렬되있어 범위 산정하기 힘들다.
  1. ROWNUM은 무조건 1부터 시작되어야해 BETWEEN을 사용하면 문제가 생겨 또 하나의 SELECT를 생성해 감싼 후 ROWNUM이 아닌 하나의 컬럼으로 인식시켜 문제를 해결한다.
1	SELECT * FROM(
  2		SELECT ROWNUM AS RNUM, A.* FROM(
	 3		SELECT BOARD_NO,BOARD_TITLE,MEMBER_NICK,
			TO_CHAR(CREATE_DT,'YYYY-DD-MM') AS CREATE_DT,  
			READ_COUNT
			FROM BOARD
			JOIN MEMBER USING(MEMBER_NO)
			WHERE BOARD_CD=? AND
			BOARD_ST='N'
			ORDER BY BOARD_NO DESC
		) A
	)
	WHERE RNUM BETWEEN ? AND ?

이렇게 수행된 모든 값들을 한번에 페이지로 보낼수 없기 때문에

Map를 사용해 한번에 전달할 수 있다.

Map<String, Object> map = new HashMap<String, Object>();
map.put("boardName", boardName);
map.put("pagination", pagination);
map.put("boardList", boardList);

map 객체를 생성해 K:String(문자열) , V:Object(모든자료형)으로 타입 지정한다.

map에는 put으로 값을 추가한다( tmi:ArrayList는 .add)

그 다음 Servlet에서 jsp로 forward한다.

//게시판 이름, 페이지네이션 객체, 게시글 리스트 3개를 한번에 반환하는 service 호출
Map<String, Object> map = service.selectBoardList(type,cp);
			
//request범위로 map을 세팅
req.setAttribute("map", map);
			
String path = "/WEB-INF/views/board/boardList.jsp";
RequestDispatcher dispatcher = req.getRequestDispatcher(path);
			
dispatcher.forward(req, resp);

0개의 댓글