[포트폴리오 페이지]_11단계_CRUD 게시판 구현_(feat.페이징 처리)

2022. 4. 18. 16:10[Spring]_/[Spring]_포트폴리오 페이지 만들기

728x90
반응형

[환경]

 

개발툴 : IntelliJ

DB : oracle

프레임워크 : spring , mybatis

 

----

개발 목표 : 기존에 만든 게시판에서 페이징 처리가 가능하도록 기능 추가

 

[완료화면]

 

10개씩 보기

20개씩 보기

 

이전 조회 기능에서 변경점]

 

https://yn971106.tistory.com/77?category=1000475 

 

[포트폴리오 페이지]_9단계_CRUD 게시판 구현_(feat.조회기능 구현)

[환경] 개발툴 : IntelliJ DB : oracle 프레임워크 : spring , mybatis ---- 개발 목표 : 오라클 디비를 이용해서 게시판 CRUD 중 R(read) 만들기 [완료 화면] [디렉토리] [설명] board에 관한 controller 와 VO..

yn971106.tistory.com

 

 

아래의 코드에서 

data.forEach(function(value){
                    console.log(value);
                        html += '<tr>';
                        html += '<td>'+value.bno+'</td>';
                        html += '<td>'+value.title+'</td>';
                        html += '<td>'+value.writer+'</td>';
                        html += '<td>'+value.regdate+'</td>';
                        html += '<td>'+value.viewcnt+'</td>';
                        html += '</tr>';
                });

                $('#table').empty()
                $('#table').append(html)

fetch 에서 데이터를 받아오면 그값을 html에 담아서 append 하는 방식에서 다음 방식으로 변경

.then(data => {

    for (let i = 0; i < data.length; i++) {

        let node = document.createElement('tr');
        const template = `
                        <th>\${data[i].bno}</th>
                        <th>\${data[i].title}</th>
                        <th>\${data[i].writer}</th>
                        <th>\${data[i].regdate}</th>
                        <th>\${data[i].viewcnt}</th>
                        `
        node.innerHTML = template;
        tbody.appendChild(node);

    }
    ;
});

가독성이 더 보기 좋아졌습니다.

 

------

[ 페이징 처리 ]  

설계:

1번 : 10개씩, 15개씩, 20개씩 보기를 선택시 그에 맞게 리스트가 변경된다.

2번 : 페이지 번호 클릭시 --개씩 보기의 기능이 적용된 상태에서 선택한 페이지의 게시글이 나오게 한다.

 

html]

<select id="selectview">
    <option value="10" selected="selected">10개씩 보기</option>
    <option value="15">15개씩 보기</option>
    <option value="20">20개씩 보기</option>
</select>

selected 옵션을 통해 default 값은 10으로 지정하였습니다.

<span id="nav"></span>

테이블 하단에 a 태그인 페이징 넘버 리스트가 올 곳을 만들었습니다.

 

Script 소스코드]

let regibtn = document.querySelector('.regi');
let tbody = document.querySelector('#table');
let viewcnt = document.querySelector('#selectview');
let nav = document.querySelector('#nav');

regibtn.onclick = function () {
    $('#main_content').load("/regi/loader", function () {

    });
}


let cnt;
let totalpagecnt;


await counttotal();
createPagenation();
await createBoard(1);

viewcnt.onchange =function(){
    createPagenation()
    createBoard(1)
}


async function counttotal() {

    await fetch('/board/boardcount.do', {
        method: "POST",
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({})
    }).then(res => res.json())
        .then(data => {
            cnt = data;
        })
}


function createPagenation() {

    while(nav.firstChild){
        nav.removeChild(nav.firstChild);
    }

    //총 페이지 수
    totalpagecnt = Math.ceil(cnt / viewcnt.value);
    //페이지 숫자 생성.
    for (let i = 1; i <= totalpagecnt; i++) {
        //html 생성하기.
        let node = document.createElement('a');
        const template = `
        <a class="navclick" href="javascript:void(0)">\${i}</a>
        `
        node.innerHTML = template;

        node.querySelector('a').onclick = function () {

            createBoard(i);

        }
        nav.appendChild(node);
    }

}


async function createBoard(nowpage) {

    while(tbody.firstChild){
        tbody.removeChild(tbody.firstChild);
    }

    await fetch('/board/search.do', {
        method: "POST",
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            view: viewcnt.value, // ~만큼 보기
            pagenum: nowpage // 페이지 숫자클릭넘버.
        })
    }).then(res => res.json())
        .then(data => {

            for (let i = 0; i < data.length; i++) {

                let node = document.createElement('tr');
                const template = `
                                <th>\${data[i].bno}</th>
                                <th>\${data[i].title}</th>
                                <th>\${data[i].writer}</th>
                                <th>\${data[i].regdate}</th>
                                <th>\${data[i].viewcnt}</th>
                                `
                node.innerHTML = template;
                tbody.appendChild(node);

            }
            ;
        });

}

js 설명]

 

1. 게시판 총 count를 가져오는 함수.

async function counttotal() {

    await fetch('/board/boardcount.do', {
        method: "POST",
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({})
    }).then(res => res.json())
        .then(data => {
            cnt = data;
        })
}

1-1 ] Controller

@RequestMapping("/board/boardcount.do")
@ResponseBody
public Integer searchcount() throws Exception{
    Integer result = boardService.searchcnt();
    System.out.println("result = " + result);
    return result;
}

 

Service, ServiceImpl , Mapper 생략

 

1-2 ] Mapper.xml

<select id="searchcnt" resultType="int">
    select count(0) from board
</select>

바라보는 테이블의 총수를 카운트 하여 Int 로 반환합니다.

fetch 통신 이후에는 cnt 라는 변수에 해당 값을 저장합니다.

 

2. 페이징 함수

function createPagenation() {

    while(nav.firstChild){
        nav.removeChild(nav.firstChild);
    }

    //총 페이지 수
    totalpagecnt = Math.ceil(cnt / viewcnt.value);
    //페이지 숫자 생성.
    for (let i = 1; i <= totalpagecnt; i++) {
        //html 생성하기.
        let node = document.createElement('a');
        const template = `
        <a class="navclick" href="javascript:void(0)">\${i}</a>
        `
        node.innerHTML = template;

        node.querySelector('a').onclick = function () {

            createBoard(i);

        }
        nav.appendChild(node);
    }

}

우선 호출시 자식 노드를 지우고 시작합니다 ( 지우지 않으면 계속 쌓이는 버그발생)

 

총 페이지 수 = > 게시판의 총 게시물 / 얼만큼 보여줄건지의 값

ex) 54개의 게시물 -> 10개씩 보기 를 선택하면 총 5개의 페이지가 생길 것입니다.

 

페이지 숫자는 for문을 통해 페이지의 수만큼 반복하고 a 태그를 생성합니다.

생성과 동시에 이벤트를 부착하고 createboard 에 각각의 숫자에 해당하는 값을 파라미터로 전달합니다.

 

3. 게시판 생성 부분

async function createBoard(nowpage) {

    while(tbody.firstChild){
        tbody.removeChild(tbody.firstChild);
    }

    await fetch('/board/search.do', {
        method: "POST",
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            view: viewcnt.value, // ~만큼 보기
            pagenum: nowpage // 페이지 숫자클릭넘버.
        })
    }).then(res => res.json())
        .then(data => {

            for (let i = 0; i < data.length; i++) {

                let node = document.createElement('tr');
                const template = `
                                <th>\${data[i].bno}</th>
                                <th>\${data[i].title}</th>
                                <th>\${data[i].writer}</th>
                                <th>\${data[i].regdate}</th>
                                <th>\${data[i].viewcnt}</th>
                                `
                node.innerHTML = template;
                tbody.appendChild(node);

            }
            ;
        });

}

파라미터로 지금 바라보고 있는 페이지 를 받습니다.

fetch 통신으로 보여줄 게시판의 수와 지금 바라보고 있는 페이지의 값을 전달합니다.

 

3-1] Controller

@RequestMapping(value = "/board/search.do")
@ResponseBody
public String boardSearchPOST(@RequestBody Map<String, String> map) throws Exception{
    System.out.println(" board 조회시작= ");
    Integer viewcnt = Integer.parseInt(map.get("view"));
    Integer nowpage = Integer.parseInt(map.get("pagenum"));

    Integer start = viewcnt * (nowpage-1) +1;
    Integer last = start + viewcnt -1;

    System.out.println("start + last = " + start + last);
    List list = boardService.boardSearch(start,last);


    System.out.println("list = " + list);
    System.out.println(" board 조회끝= ");
    String json = new Gson().toJson(list);
    System.out.println("json = " + json);
    return json;
}

게시판 기준으로.

 

시작할 번호 = 보여줄 게시판 수 * (지금 바라보는 페이지 번호 - 1) + 1

ex ) 10개씩 보여줄 것이며, 지금 페이지 2를 선택했다고 가정시.

      10 * (2 -1 ) +1 = 11

      즉 시작번호가 11부터라는 의미입니다.

 

마지막 번호 = 시작할 번호 + 보여줄 게시판 수 - 1

ex )  10개씩 보여줄 것이며, 지금 페이지 2를 선택했다고 가정 시.

       11 + 10 - 1 = 20

       즉 시작은 11~ 20 번까지의 게시판을 불러오겠다는 의미입니다.

 

Service, ServiceImpl , Mapper 생략

 

3-2.] Mapper.xml

 

<select id="boardSearch" resultType="com.yoon.model.BoardVO">
    select bno,title,writer,regdate,viewcnt
    from board
    where bno between #{start} AND #{last}
    order by regdate desc

</select>

해당 쿼리는

start , last 의 int 값을 받고 게시판 객체를 반환하게 됩니다. 순서는 작성일 기준으로 내림차순입니다.

between을 이용해서 사이의 값만 쿼리로 가져오는 것입니다.

 

3-3] 받아온 값 처리

for (let i = 0; i < data.length; i++) {

    let node = document.createElement('tr');
    const template = `
                    <th>\${data[i].bno}</th>
                    <th>\${data[i].title}</th>
                    <th>\${data[i].writer}</th>
                    <th>\${data[i].regdate}</th>
                    <th>\${data[i].viewcnt}</th>
                    `
    node.innerHTML = template;
    tbody.appendChild(node);

}
;

이를 Json 형식으로 전달하고, script 부분에서는 . 을 통해 key 값으로 접근하여

반복문을 통해 template를 생성합니다.

그리고 이를 tbody에 자식노드로 붙입니다.

 

 

728x90
반응형