Web/Spring
[Spring/스프링] - 스프링 부트 페이지내이션 /Pageable
poopooreum
2024. 9. 13. 02:38
반응형
안녕하세요!
오늘은 스프링 부트에서 페이징을 적용시키는 방법과 페이징네이션의 개념에 대해서 업로드를 해보겠습니다.
✏️ 페이지내이션이란?
페이징내이션(Pagination)은 데이터를 여러 페이지로 나누어 보여주는 기술입니다. 웹사이트나 애플리케이션에서 많은 양의 데이터를 한꺼번에 보여주면 사용자가 정보를 빠르게 찾기 어려워지기 때문에, 페이징내이션을 사용하여 데이터를 효율적으로 분할해 사용자에게 제공합니다. 페이징내이션은 보통 다음과 같은 요소로 구성됩니다:
- 현재 페이지: 사용자가 현재 보고 있는 페이지 번호.
- 이전/다음 페이지: 페이지 간 이동을 위한 버튼 또는 링크.
- 전체 페이지 수: 총 데이터 양을 기준으로 계산된 페이지 수.
- 페이지당 항목 수: 한 페이지에 보여줄 데이터의 개수.
이를 통해 사용자 경험을 개선하고, 서버의 부하를 줄일 수 있습니다.
✏️ 페이징이란?
전체 데이터를 일정한 크기의 덩어리(페이지)로 분할하는 과정을 가리킵니다. 예를 들어, 100개의 결과가 있고, 페이지당 10개씩 보여준다면 총 10개의 페이지가 생기게 됩니다. 이는 대량의 데이터를 작은 덩어리로 나누어 사용자가 한 번에 처리하기 편하게 해줍니다
✏️ 슬라이싱이란?
데이터의 일부를 선택하는 것으로, 특정 페이지에 해당하는 데이터 덩어리를 추출하는 과정을 의미합니다. 예를 들어, 100개의 결과 중 3페이지에 해당하는 결과들을 가져온다거나, 특정 페이지 범위 내의 결과를 추출하는 것이 슬라이싱입니다.
✏️ Entity 생성하기
public class Inquiry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idx", nullable = false)
private Integer idx;
@NotNull
@Column(name = "service", nullable = false, length = 50)
private String service;
@NotNull
@Column(name = "name", nullable = false, length = 30)
private String name;
@NotNull
@Column(name = "company", nullable = false, length = 30)
private String company;
@NotNull
@Column(name = "tel", nullable = false, length = 10)
private String tel;
@NotNull
@Column(name = "email", nullable = false, length = 50)
private String email;
@NotNull
@Column(name = "question", nullable = false)
private String question;
public InquiryVo toInquiryVo(){
return InquiryVo.builder()
.idx(this.getIdx())
.service(this.getService())
.name(this.getName())
.company(this.getCompany())
.tel(this.getTel())
.email(this.getEmail())
.question(this.getQuestion())
.build();
}
✏️ DTO 생성하기
@Getter
@Setter
public class InquiryGetDTO {
@NotNull
@Min(1)
private Integer page;
}
✏️ Vo 생성
@Builder
@Getter
public class InquiryVo {
private Integer idx;
private String service;
private String name;
private String company;
private String tel;
private String email;
private String question;
}
✏️ Controller 작성
public class InquiryController{
private final InquiryService inquiryService;
@GetMapping("")
public ResponseEntity<ResponseDTO<Object>> getInquiry(@Valid @RequestBody InquiryGetDTO inquiryGetDTO,Errors errors) {
log.error("페이징");
if(errors.hasErrors()) {
return new ResponseEntity<>(ResponseDTO.builder().error(true).message("").data(null).build(), HttpStatus.BAD_REQUEST);
}
List<Inquiry> inquiryList = inquiryService.getInquiryList();
if(inquiryList.isEmpty()) {
return new ResponseEntity<>(ResponseDTO.builder().error(true).message("").data(null).build(), HttpStatus.NOT_FOUND);
}
int page = inquiryGetDTO.getPage();
Page<InquiryVo> inquiryVoPage = inquiryService.getInquiryPages(PageRequest.of(page-1,10),inquiryList);
int maxPage = inquiryVoPage.getTotalPages();
int currentPageElementNumber = inquiryVoPage.getNumberOfElements();
List<InquiryVo> inquiryVoList = inquiryVoPage.getContent();
InquiryPagingVo inquiryPagingVo = inquiryService.setInquiryPagingVo(inquiryVoList,maxPage,currentPageElementNumber);
return new ResponseEntity<>(ResponseDTO.builder().error(false).message("").data(inquiryPagingVo).build(), HttpStatus.OK);
}
}
✏️ InquiryService 작성
public interface InquiryService {
void addInquiry(String service, String name, String company, String tel, String email, String question);
List<Inquiry> getInquiryList();
Page<InquiryVo> getInquiryPages(Pageable pageable, List<Inquiry> inquiryList);
InquiryPagingVo setInquiryPagingVo(List<InquiryVo> inquiryVoList, int maxPage, int currentPageElementNumber);
}
✏️ InquiryServiceImpl 구현
public class InquiryServiceImpl implements InquiryService {
private final InquiryRepository inquiryRepository;
@Override
public void addInquiry(String service, String name, String company, String tel, String email, String question) {
Inquiry inquiry = Inquiry.builder()
.service(service)
.name(name)
.company(company)
.tel(tel)
.email(email)
.question(question)
.build();
inquiryRepository.save(inquiry);
}
@Override
public List<Inquiry> getInquiryList() {
return inquiryRepository.findAll();
}
@Override
public Page<InquiryVo> getInquiryPages(Pageable pageable, List<Inquiry> inquiryList) {
List<InquiryVo> inquiryVoList = new ArrayList<>();
for(Inquiry inquiry : inquiryList) {
inquiryVoList.add(inquiry.toInquiryVo());
}
int pageSize = pageable.getPageSize();
int currentPage = pageable.getPageNumber();
int startIndex = currentPage * pageSize;
List<InquiryVo> pagedInquiry = new ArrayList<>();
if(inquiryVoList.size()<startIndex){
pagedInquiry = Collections.emptyList();
}
else{
int toIndex = Math.min(startIndex+pageSize, inquiryVoList.size());
pagedInquiry = inquiryVoList.subList(startIndex, toIndex);
}
return new PageImpl<>(pagedInquiry, pageable, inquiryVoList.size());
}
@Override
public InquiryPagingVo setInquiryPagingVo(List<InquiryVo> inquiryVoList, int maxPage, int currentPageElementNumber) {
return InquiryPagingVo.builder()
.inquiryVos(inquiryVoList)
.maxPage(maxPage)
.currentPageElementNumber(currentPageElementNumber).build();
}
}
✏️ 응답 결과
{
"page" : "1"
}
{
"error": false,
"message": "문의 사항 목록 조회를 완료하였습니다.",
"data": {
"inquiryVos": [
{
"idx": 1,
"service": "서비스1",
"name": "정푸름",
"company": "시그마",
"tel": "02-123-4567",
"email": "poo@sigma.com",
"question": "qmfkqmfkdmfd"
},
{
"idx": 2,
"service": "서비스1",
"name": "철수1",
"company": "삼성1",
"tel": "1234",
"email": "p@gmail.com",
"question": "ㅇㄹㅁㅇㄹㅁㄴㄹ"
},
{
"idx": 3,
"service": "서비스1",
"name": "철수2",
"company": "삼성2",
"tel": "123",
"email": "p@gmail.com",
"question": "ㅁㄴㅇㄹㅁㄴㅇㄹㅁㄴ"
},
{
"idx": 4,
"service": "서비스1",
"name": "철수5",
"company": "삼성5",
"tel": "231",
"email": "p@gmail.com",
"question": "ㅁㄴㅇㄹㅁㄴㅇㄹ"
},
{
"idx": 5,
"service": "서비스1",
"name": "철수6",
"company": "삼성6",
"tel": "456",
"email": "p@gmail.com",
"question": "ㅇㄹㅁㅇㄹ"
},
{
"idx": 6,
"service": "서비스1",
"name": "철수7",
"company": "삼성7",
"tel": "213",
"email": "p@gmail.com",
"question": "ㅇㅁㄴㄹㅁㄴㅇㄹ"
},
{
"idx": 7,
"service": "서비스1",
"name": "철수8",
"company": "삼성8",
"tel": "5131",
"email": "p@gmail.com",
"question": "ㅁㄴㅇㄹㅁㄴㅇㄹ"
},
{
"idx": 8,
"service": "서비스1",
"name": "철수9",
"company": "삼성9",
"tel": "51321",
"email": "p@gmail.com",
"question": "ㅇㅁㄴㄹㅁㄴㅇㄹ"
},
{
"idx": 9,
"service": "서비스1",
"name": "철수10",
"company": "삼성10",
"tel": "3555",
"email": "p@gmail.com",
"question": "ㅁㄴㅇㄹㅁㄴㅇㄹ"
},
{
"idx": 10,
"service": "서비스1",
"name": "철수11",
"company": "삼성11",
"tel": "124564",
"email": "p@gmail.com",
"question": "ㅁㅇㄹ퓨ㅜㅜㅜ"
}
],
"maxPage": 2,
"currentPageElementNumber": 10
}
}
{
"page" : "2"
}
{
"error": false,
"message": "문의 사항 목록 조회를 완료하였습니다.",
"data": {
"inquiryVos": [
{
"idx": 11,
"service": "서비스1",
"name": "철수12",
"company": "삼성12",
"tel": "214564",
"email": "p@gmail.com",
"question": "ㅇㄹㅇㅍㅁㄹㅁㄴㅇㄹ"
}
],
"maxPage": 2,
"currentPageElementNumber": 1
}
}
반응형