JPA์์ Pageable๋ก ํ์ด์ง ์ฒ๋ฆฌํ๊ธฐ
Pageable๋ก ํ์ด์ง ์ฒ๋ฆฌํ๊ธฐ
Pageable์ ์ด์ฉํด JPA์์ ํ์ด์ง ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์๋ณด์.
TaskRepository
Task
๋ผ๋ ๋ชจ๋ธ์ ๋ฐ๋ TaskRepository
๋ฅผ ๋ง๋ค๊ณ , ํ์ด์ง ๋จ์๋ก Task๋ฅผ ๋ฐ๋๋ก ํด๋ณด์.
import com.vividswan.studymate.model.Task;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TaskRepository extends JpaRepository<Task ,Long> {
}
์ฐ์ JpaRepository
์ Task
ํ์
๊ณผ Task
์ PK ํ์
์ผ๋ก ์ ๋ค๋ฆญ ํ์ฌ ์์๋ฐ๋ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๋ฉด, Task Entity์ ๋ํ CRUD ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ TaskRepository
๊ฐ ๋ง๋ค์ด์ง๋ค.
์ฌ๊ธฐ์ ํ์ด์ง ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ ์ํ ์ฝ๋๋ฅผ ์ถ๊ฐํ์.
package com.vividswan.studymate.repository;
import com.vividswan.studymate.model.Task;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TaskRepository extends JpaRepository<Task ,Long> {
Page<Task> findAllByUserIdAndIsSuccess(Long userId, int isSuccess, Pageable pageable);
}
findAllByUserIdAndIsSuccess
Task Table์์ userId
๋ผ๋ ์์ฑ๊ณผ isSuccess
๋ผ๋ ์์ฑ์ ์
๋ ฅ๋ฐ์ ์กฐํํ ์ ์๋ ๋ฉ์๋๋ฅผ ๋ง๋ค์๋ค.
Page
return ๊ฐ์ ํ์ด์ง ๋จ์์ Task
ํ์
์ด๋ค.
๋ฉ์๋ ํ๋ผ๋ฏธํฐ
Long userId, int isSuccess, Pageable pageable
๋ฉ์๋์ ๋ค์ด๊ฐ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํด๋ณด์.
userId ์์ฑ๊ณผ isSuccess ์์ฑ์ ๋ฐํ์ผ๋ก ์กฐํ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ ๊ฐ์ ํ๋ผ๋ฏธํฐ์ ๋ฃ์ด์ค์ผ ํ๋ค.
๊ทธ ๋ค์ ๊ฐ์ฅ ์ค์ํ Page์ ๋ํ ์ค์ ๊ฐ์ ๋ด์ ์ค Pageable pageable
์ ํ๋ผ๋ฏธํฐ๋ก ๋ฃ์ด์ค์ผ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
TaskService
package com.vividswan.studymate.service;
import com.vividswan.studymate.config.auth.PrincipalDetails;
import com.vividswan.studymate.model.Task;
import com.vividswan.studymate.repository.TaskRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class TaskService2 {
private final TaskRepository taskRepository;
@Transactional(readOnly = true)
public Page<Task> findList(PrincipalDetails principalDetails, @PageableDefault(size=8, sort = "deadline", direction = Sort.Direction.ASC) Pageable pageable) {
return taskRepository.findAllByUserIdAndIsSuccess(principalDetails.getUserId(),0, pageable);
}
}
๋ค์๊ณผ ๊ฐ์ด Service ๊ณ์ธต์์ ํ์ด์ง ๋จ์๋ก Task ๊ฐ์ฒด๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋ findList
๋ฉ์๋๋ฅผ ๋ง๋ค์ด์ฃผ์.
@Transactional(readOnly = true)
์ฝ์
, ์์ , ์ญ์ ๊ฐ ์๋ ์กฐํ๋ง ํ๋ ๋ฉ์๋์ด๋ฏ๋ก readOnly
ํธ๋์ญ์
์ ์ ์ธํด ์ค๋ค.
PrincipalDetails principalDetails
UserId๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํด ์ ์ธํ๋ค.
spring security context holder์ ์๋ ์ธ์
๊ฐ์ ํตํด userId๋ฅผ ๋ถ๋ฌ์จ๋ค.
@PageableDefault
@PageableDefault(size=8, sort = "deadline", direction = Sort.Direction.ASC) Pageable pageable
@PageableDefault ์ด๋ ธํ ์ด์ ์ ์ ์ธํด ์ฃผ๊ณ page์ ๋ํ ์ค์ ์ ํ ์ ์๋ค.
- size : ํ ํ์ด์ง์ ๋ด์ ๋ชจ๋ธ์ ์๋ฅผ ์ ํ ์ ์๋ค.
- sort : ์ ๋ ฌ์ ๊ธฐ์ค์ด ๋๋ ์์ฑ์ ์ ํ ์ ์๋ค.
- direction : ์ค๋ฆ์ฐจ์๊ณผ ๋ด๋ฆผ์ฐจ์ ์ค ๊ธฐ์ค์ ์ ํํ๋ค.
- Pageable pageable : PageableDefault ๊ฐ์ ๊ฐ๊ณ ์๋ ๋ณ์๋ฅผ ์ ์ธํ๋ค.
ํ์ด์ง ์ถ๋ ฅ
@GetMapping("/todolist/proceeding")
@ResponseBody
public Page<Task> taskView(Model model, @AuthenticationPrincipal PrincipalDetails principalDetails, @PageableDefault(size=8, sort = "deadline", direction = Sort.Direction.ASC) Pageable pageable, int page){
Page<Task> pagingTasks = taskService.findList(principalDetails, pageable);
return pagingTasks;
}
์ปจํธ๋กค๋ฌ์์ @ResponseBody๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ JSON ํํ๋ก ๋ฐ์์ ํ์ธํด๋ณด์.
๊ฒฐ๊ณผ
{
"content": [
{
"id": 3,
"title": "1234",
"content": "<p>12345</p>",
"createDate": "2020-10-13T15:31:32.965",
"deadline": "2020-10-07T15:31:00",
"user": {
"id": 1,
"username": "vividswan",
"nickname": "์ํ",
"email": "vividswan@naver.com",
"password": "$2a$10$V.vNh2.zATNZqTeINZD57eGm6LD4C1ZxBJVah12MVZ6FBs1/tvKki",
"role": "USER",
"createDate": "2020-10-13T14:27:09.054"
},
"feedbacks": [
],
"isSuccess": 0,
"stringDeadline": "2020/10/07 03:31"
}
],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"pageNumber": 0,
"pageSize": 8,
"offset": 0,
"paged": true,
"unpaged": false
},
"totalPages": 1,
"totalElements": 1,
"last": true,
"numberOfElements": 1,
"first": true,
"size": 8,
"number": 0,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"empty": false
}
์์ ๊ฐ์ด ํ์ด์ง ์ฒ๋ฆฌ๋์ด ๊ฒฐ๊ณผ๊ฐ ๋์ด์ ํ์ธํ ์ ์๋ค.
JSON์ ํฌํจ๋ last
, first
, pageNumber
, pageSize
๋ฑ์ ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ๊ตฌํํ ๋ ํ์ฉํ ์ ์๋ค.