일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 반복문
- SQL 튜닝
- SpringSecurity 로그아웃
- 상속
- 객체지향
- 배열
- spring 게시판 삭제
- 함수
- 친절한 SQL
- 비교 연산자
- 스프링시큐리티 로그아웃
- 예약어
- StringBuffer
- 산술 연산자
- SQL튜닝
- 객체
- SQL
- join
- @PreAuthorize("isAuthenticated()")
- 논리 연산자
- 인텔리제이 Web 애플리케이션
- 친절한 SQL 튜닝
- 연산자
- java
- 이클립스 설치
- 오버로딩
- 식별자
- SpringSecurity 로그인
- 오버라이딩
- 자바의정석
Archives
- Today
- Total
gi_dor
스프링부트 + MyBatis +MYSQL 페이징 처리 본문
728x90
마이페이지 → 1:1 문의 내역에 대해 페이징 처리를 하려고 합니다
가장 기본적인 List 로 출력 했습니다 , 테스트용 더미 데이터를 추가해보겠습니다
<!-- 1:1 문의사항 글 갯수 파악하기 -->
<select id="countInquiry" parameterType="string" resultType="int">
select count(*)
from INDIVIDUAL_INQUIRIES i , USER u
where i.INQUIRY_USER_NO = u.USER_NO
and u.USER_ID = #{id}
</select>
<!--페이징 되어있는 1:1문의 내역 조회하기 -->
<select id="selectInquiryListPaging" resultType="com.example.bookhub.user.dto.InquiryListDTO">
select
i.INDIVIDUAL_INQUIRY_NO as no,
i.INQUIRY_CATEGORY_NO as "faqCategory.no",
f.FAQ_CATEGORY_NAME as "faqCategory.name",
i.INQUIRY_USER_NO as "user.no",
u.USER_ID as "user.id",
i.INDIVIDUAL_INQUIRY_TITLE as title,
i.INDIVIDUAL_INQUIRY_CONTENT as content,
i.INDIVIDUAL_INQUIRY_ANSWER_YN as answerYn,
i.INDIVIDUAL_INQUIRY_DELETE_YN as deleteYn,
i.INDIVIDUAL_INQUIRY_CREATE_DATE as createdDate ,
i.INDIVIDUAL_INQUIRY_UPDATE_DATE as updatedDate,
u.USER_NAME as "user.name"
from INDIVIDUAL_INQUIRIES i , USER u , FAQ_CATEGORIES f
where i.INQUIRY_USER_NO = u.USER_NO
and i.INQUIRY_CATEGORY_NO = f.FAQ_CATEGORY_NO
and u.USER_ID = #{id}
order by i.INDIVIDUAL_INQUIRY_CREATE_DATE DESC
LIMIT #{offset} ,10
</select>
LIMIT - 결과중 처음부터 몇개만 가져오기
SELECT * FROM 테이블명 LIMIT 10; -- 처음 부터 10개만 출력하기 (1 ~ 10)
SELECT * FROM 테이블명 LIMIT 100, 10; -- 100번째부터 그 후 10개 출력하기 (101 ~ 110)
OFFSET - 어디서부터 가져올지
-- 10행씩 출력
--1페이지
select * from member ORDERS LIMIT 10 OFFSET 0;
-- 1 2 3 4 5 6 7 8 9 10
-- 2페이지
select * from member ORDERS LIMIT 10 OFFSET 10;
-- 11 12 13 14 15 16 17 18 19 20
SELECT * FROM 테이블명 ORDERS LIMIT 20 OFFSET 5; -- 6 행 부터 25행 까지 출력 (6 ~ 25)
-- 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
-- limit 5, 20 과 같다고 보면 된다.
SELECT * FROM 테이블명 ORDERS LIMIT 5, 20;
Pagination
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserPagination {
// 화면에 보여줄 글, 행의 갯수
private int rows = 10;
// 페이징 네비게이션의 보여줄 페이지 갯수 1, 2 , 3 , 4 ,5 > >>
private int pages = 5;
// 전체 글의 갯수
private int totalRows;
// 전체 페이지 갯수 totalPages = 5 --> 글 갯수 26~30개
private int totalPages;
// 전체 페이지네이션 바에 표시할 전체 블럭 갯수
private int totalBlocks;
// 현재 페이지 번호
private int currentPage;
// 현재 블럭 번호
private int currentBlock;
private int begin;
private int end;
private int beginPage;
private int endPage;
// 현재 첫번째 페이지 ,마지막 페이지 구분
private boolean isFirst;
private boolean isLast;
private void init() {
// 글이 존재하는지
if (totalRows > 0) {
// 전체 페이지 갯수 계산하기
this.totalPages = (int) Math.ceil((double) totalRows / rows);
// 전체 페이지 블럭 갯수 계산
this.totalBlocks = (int) Math.ceil((double) totalPages / pages);
// 현재 블럭 계싼
this.currentBlock = (int) Math.ceil((double) currentPage / pages);
// 게시글 조회범위
this.begin = (currentPage - 1) * rows + 1;
this.end = currentPage * rows;
// 페이지 내비게이션 출력범위 계산
this.beginPage = (currentBlock - 1) * pages + 1;
this.endPage = currentBlock * pages;
if (currentBlock == totalBlocks) {
this.endPage = this.totalPages;
}
if (currentPage == 1) {
this.isFirst = true;
}
if (currentPage == totalPages) {
this.isLast = true;
}
}
}
public UserPagination(int currentPage, int totalRows) {
this.totalRows = totalRows;
this.currentPage = currentPage;
init();
}
public UserPagination(int currentPage, int totalRows, int rows) {
this.totalRows = totalRows;
this.currentPage = currentPage;
this.rows = rows;
init();
}
public UserPagination(int currentPage, int totalRows, int rows, int pages) {
this.totalRows = totalRows;
this.currentPage = currentPage;
this.rows = rows;
this.pages = pages;
init();
}
}
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class InquiryListDTO {
// 문의사항 번호
Long no;
// 글 카테고리
FaqCategory faqCategory;
// 문의사항 제목
String title;
// 문의사항 내용
String content;
// 문의사항 답변여부
boolean answerYn;
// 글 삭제 여부
boolean deleteYn;
// 작성날짜
LocalDateTime createdDate;
// 글 수정 날짜
LocalDateTime updatedDate;
// 글작성 사용자 정보
User user;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PageListDTO<T> {
private List<T> items;
private UserPagination userPagination;
}
제네릭 타입을 사용하여 페이지 목록을 나타낸다
- items: 페이지에 포함된 요소의 목록을 나타내는 제네릭 타입의 리스트입니다. 이는 페이지에 표시될 항목을 저장
- userPagination: 사용자 페이지네이션 정보를 나타내는 클래스.
사용자 페이지네이션은 페이지 내비게이션을 관리하기 위해 사용되며 페이지네이션에 필요한 정보를 저장
<T> 제네릭의 타입 매개변수다. 여러 종류의 타입에 대한 클래스를 작성할 수 있다
타입 매개변수로 인해 계속해서 ListDTO + Pageination을 담은 클래스를 만들지 않고도 사용할 수 있다
코드의 재사용성도 높아지고 중복된 코드를 줄일 수 있다
@Mapper
public interface MyPageMapper {
List<InquiryListDTO>selectInquiryListPaging(@Param("id")String id , @Param("offset")int offset);
}
@Slf4j
@Service
@RequiredArgsConstructor
public class MyPageService {
public PageListDTO<InquiryListDTO> getInquiryListByIdPage(String id , int page) {
// 사용자 정보조회
User user = userMapper.selectUserById(id);
// 사용자의 아이디로 전체 작성된 1:1문의 갯수 조회
int totalRows = myPageMapper.countInquiry(user.getId());
// 페이징 정보
UserPagination userPagination = new UserPagination(page , totalRows);
int offset = userPagination.getBegin() -1;
// 페이징된 결과 조회
List<InquiryListDTO> inquiryListDTO = myPageMapper.selectInquiryListPaging(user.getId(), offset);
// <T> 제네릭 타입매개변수 사용
PageListDTO<InquiryListDTO> pageListDTO = new PageListDTO<>();
pageListDTO.setItems(inquiryListDTO);
pageListDTO.setUserPagination(userPagination);
// PageListDTO<InquiryListDTO> pageListDTO = new PageListDTO<>(inquiryListDTO,userPagination);
return pageListDTO;
}
}
<div>
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center pagination-sm">
<!-- 첫 페이지로 이동하는 링크 -->
<li class="page-item">
<a class="page-link" th:if="${page.currentPage > 1}"
th:href="@{/mypage/list/inquiryList(page=1)}" >«</a>
<span class="page-link disabled" th:unless="${page.currentPage > 1}">«</span>
</li>
<!-- 이전 페이지 링크 -->
<li class="page-item">
<a class="page-link" th:attr="data-page=${page.currentPage - 1}" onclick="page(event)"
th:href="@{/mypage/list/inquiryList(page=${page.currentPage - 1})}"
th:if="${page.currentPage > 1}"><</a>
<span class="page-link disabled" th:unless="${page.currentPage > 1}"><</span>
</li>
<!-- 페이지 번호를 표시하기 위한 리스트 아이템 -->
<li class="page-item" th:each="pageNo : ${#numbers.sequence(page.beginPage, page.endPage)}"
th:class="${pageNo == page.currentPage} ? 'active' : ''"> <!-- 현재 페이지와 페이지 번호를 비교하여 활성화 클래스를 동적으로 설정 -->
<a class="page-link" th:attr="data-page=${pageNo}" onclick="page(event)"
th:href="@{/mypage/list/inquiryList(page=${pageNo})}" th:text="${pageNo}"></a>
</li>
<!-- 다음 페이지 링크 -->
<li class="page-item">
<a class="page-link" th:attr="data-page=${page.currentPage + 1}" onclick="page(event)"
th:href="@{/mypage/list/inquiryList(page=${page.currentPage + 1})}"
th:if="${page.currentPage < page.totalPages}">></a>
<span class="page-link disabled" th:unless="${page.currentPage < page.totalPages}">></span>
</li>
<!-- 마지막 페이지로 이동하는 링크 -->
<li class="page-item">
<a class="page-link" th:if="${page.currentPage < page.totalPages}"
th:href="@{/mypage/list/inquiryList(page=${page.totalPages})}">»</a>
<span class="page-link disabled" th:unless="${page.currentPage < page.totalPages}">»</span>
</li>
</ul>
</nav>
</div>
<li class="page-item">
<a class="page-link" th:if="${page.currentPage > 1}"
th:href="@{/mypage/list/inquiryList(page=1)}" >«</a>
<span class="page-link disabled" th:unless="${page.currentPage > 1}">«</span>
</li>
현재 페이지가 1보다 큰 경우에만 이전 페이지로 이동하는 링크를 활성화하고, 그렇지 않은 경우 비활성화
728x90
'Back_End > SpringBoot' 카테고리의 다른 글
Spring에서 비동기 @Async (0) | 2024.08.29 |
---|---|
[Refactor] 카페인 캐싱으로 성능개선 , Ngrinder (0) | 2024.06.11 |
스프링부트 설정파일(application.properties) 암호화 (Jasypt) (0) | 2024.05.02 |
비밀번호 찾기 + 임시비밀번호 이메일전송 (0) | 2024.04.30 |
마이페이지 ver.2- SpringSecurity, MySQL , MyBatis (1) | 2024.04.25 |