프로젝트

37. 선수 목록 페이지네이션

uni5948 2022. 1. 20. 15:15

37. 선수 목록 페이지네이션

현재 선수 목록 조회 시 선수가 한 페이지에 모두 나타나고 있어 페이지네이션을 이용해 여러 페이지에 나타나도록 한다.

  • 백엔드 선수 전체 조회 수정, 전체 선수 수 조회 추가

1. PlayerRepositoy

    //선수 전체 조회
    List<Player> findAllByOrderByPlayernoDesc(Pageable pageable);
 
    //선수 전체 수 조회
    Long countAllByOrderByPlayernoDesc();
 
2. PlayerService
    //선수 전체 정보 조회
    public List<Player> getPlayerAll(Pageable pageable);
 
    //선수 전체 수 조회
    public Long getTotalPage();
 
3. PlayerServiceImpl
    //선수 전체 정보 조회
    @Override
    public List<Player> getPlayerAll(Pageable pageable) {
        return pRepositoy.findAllByOrderByPlayernoDesc(pageable);
    }
 
    //선수 전체 수 조회
    @Override
    public Long getTotalPage() {
        return pRepositoy.countAllByOrderByPlayernoDesc();
    }

4. PlayerController

    // 선수 전체 조회
    //127.0.0.1:8080/REST/playerall?page=1
    @RequestMapping(value = "/playerall", method = {RequestMethod.GET},
    consumes = MediaType.ALL_VALUE,
    produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> playerallGET(Player player,
    @RequestParam(value = "page", defaultValue = "1")int page ) {
        //페이지 네이션 처리
        PageRequest pageable = PageRequest.of(page-1, 15);
        Map<String, Object> map = new HashMap<>();
        try{
            List<Player> playerAll = pService.getPlayerAll(pageable);
            Long totalpage = pService.getTotalPage(); //등록된 전체 선수 수 조회
            map.put("status", "200");
            map.put("count", playerAll.size()); //1 페이지에 표시된 선수 숫자
            map.put("totalpage", (totalpage-1)/15+1 ); //전체 페이지
            map.put("player",playerAll );
        }
        catch(Exception e){
            e.printStackTrace();
            map.put("status", e.hashCode());
        }
        return map;
    }

5. 선수 목록 조회

선수 목록 조회

  • 프론트엔드

1. 페이지네이션을 위해 element-plus 설치

 

1-1. cmd 창에서 element-plus 설치하기

CMD> npm install element-plus --save  

 

1-2. main.js에 ui 설정하기

import { createApp } from 'vue'
import App from './App.vue'
import router from './routes';

//ui 설정
import ElementPlus from 'element-plus';
import 'element-plus/theme-chalk/index.css';

const app = createApp(App);
app.use(router);
app.use(ElementPlus);
app.mount('#app');
2. 선수 목록 페이지 페이지네이션 추가
<template>
    <div>
        <h3>선수 목록</h3>
        <input type="text" v-model="text"
            placeholder="검색" @keyup.enter="handleSearch" />
        <table border="1">
            <tr>
                <td>이름</td>
                <td>나이</td>
                <td>국적</td>
                <td>포지션</td>
                <td>몸 값</td>
            </tr>
            <tr v-for="player in players" v-bind:key="player">
                <td>{{player.playername}}</td>
                <td>{{player.playerage}}</td>
                <td>{{player.playercountry}}</td>
                <td>{{player.playerposition}}</td>
                <td>{{player.playerprice}}</td>
            </tr>
        </table>
        <hr />
            <el-pagination
                background layout="prev, pager, next" :total="totalpage"
                @current-change="handleCurrentChange">
            </el-pagination>
       
    </div>
</template>

<script>
    import axios from 'axios';
    export default {
       
        methods:{
             //페이지 이동
            async handleCurrentChange(val){
                this.page = val;
                await this.handleSearch();
            },
            async handleSearch() {
                const url = `/REST/playerall?page=${this.page}`;
                const headers = {"Content-Type":"application/json"}
                const response = await axios.get(url, {headers});
                // console.log(response);
                this.players = response.data.player;
 
                const response1 = await axios.get(url);
                // console.log(response1);
                //전체 선수 수를 통해 페이지네이션 숫자 생성
                this.totalpage = Number(response1.data.count);
            }
        },
        async created(){
            await this.handleSearch();
        },
       
        data(){
            return{
                players : [],
                page : 1,
                totalpage : 0,
                text : ''
            }
        }
    }
</script>

<style >

</style>
 
3. 화면 확인

 

 
페이지네이션 추가

 

  • 2 페이지 이동

현재 상태는 총 페이지 숫자는 표시되지만 해당 페이지로 이동이 되지 않고 있다.

console 창을 확인하면 2 페이지의 정보가 출력은 되지만 

                const response1 = await axios.get(url);
                console.log(response1);
                //전체 선수 수를 통해 페이지네이션 숫자 생성
                this.totalpage = Number(response1.data.count);
문에 url을 get한 뒤 그 정보의 count를 이용해 페이지 이동을 하는데 기존 url은 1 페이지의 정보를 가지고 있어서 자동으로 1 페이지로 돌아오게 되어있다.
이 문제를 해결하기 위해,
백엔드에 선수 전체 숫자 조회문(count)을 생성한 뒤 프론트엔드에서 url1을 생성해 조회문을 get한다.
그 후 해당 url1에 count를 이용해 2 페이지로 이동한다.

 

1. 백엔드

1-1. 전체 숫자 조회 생성(PlayerController)


    //전체 선수 숫자 조회
    //127.0.0.1:8080/REST/playercount
    @RequestMapping(value = "/playercount", method = {RequestMethod.GET},
    consumes = MediaType.ALL_VALUE,
    produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> playercountGET(Player player) {
        Map<String, Object> map = new HashMap<>();
        try{
            Long totalpage = pService.getTotalPage(); //등록된 전체 선수 수 조회
            map.put("status", "200");
            map.put("count", totalpage);
            map.put("totalpage", (totalpage-1)/15+1 ); //전체 페이지
        }
        catch(Exception e){
            e.printStackTrace();
            map.put("status", e.hashCode());
        }
        return map;
    }
 
 

1-2. 프론트엔드 수정

더보기
<template>
    <div>
        <h3>선수 목록</h3>
        <input type="text" v-model="text"
            placeholder="검색" @keyup.enter="handleSearch" />
        <table border="1">
            <tr>
                <td>이름</td>
                <td>나이</td>
                <td>국적</td>
                <td>포지션</td>
                <td>몸 값</td>
            </tr>
            <tr v-for="player in players" v-bind:key="player">
                <td>{{player.playername}}</td>
                <td>{{player.playerage}}</td>
                <td>{{player.playercountry}}</td>
                <td>{{player.playerposition}}</td>
                <td>{{player.playerprice}}</td>
            </tr>
        </table>
        <hr />
            <el-pagination
                background layout="prev, pager, next" :total="totalpage"
                @current-change="handleCurrentChange">
            </el-pagination>
       
    </div>
</template>

<script>
    import axios from 'axios';
    export default {
       
        methods:{
             //페이지 이동
            async handleCurrentChange(val){
                this.page = val;
                await this.handleSearch();
            },
            async handleSearch() {
                const url = `/REST/playerall?page=${this.page}`;
                const headers = {"Content-Type":"application/json"}
                const response = await axios.get(url, {headers});
                // console.log(response);
                this.players = response.data.player;
 
                const url1 = `/REST/playercount` //전체 선수 숫자 조회 주소 입력
                const response1 = await axios.get(url1);
                console.log(response1);
                //전체 선수 수를 통해 페이지네이션 숫자 생성
                this.totalpage = Number(response1.data.count);
            }
        },
        async created(){
            await this.handleSearch();
        },
       
        data(){
            return{
                players : [],
                page : 1,
                totalpage : 0,
                text : ''
            }
        }
    }
</script>

<style >

</style>

 

2. 2 페이지 이동 확인

2 페이지 이동