프로젝트
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 페이지 이동 확인