- ์ฌ๊ธฐ์๋ Spring Data JPA์ ๋ํ ๋ด์ฉ์ ๋ค๋ฃจ๋๋ก ํ๊ฒ ๋ค.
org. springframework. data. domain. Sort
๏ผ ์ ๋ ฌ ๊ธฐ๋ฅorg.springframework.data.domain.Pageable
๏ผ ํ์ด์ง ๊ธฐ๋ฅ(๋ด๋ถ์ Sort ํฌํจ)
PageRequest.of()
๋ผ๋ ๊ธฐ๋ฅ์ ์ด์ฉํด์ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํ๋ค.of
๋ฅผ ํตํด Pageable
์ธํฐํ์ด์ค๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.)// Pageable ๊ฐ์ฒด๋ PageRequest.of๋ก ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
@Test
public void testPagingO {
//1 page order by bno desc
Pageable pageable = PageRequest.of(0,10, Sort.by("bnoโ).descending());
Page<Board> resuLt = boardRepository.findALL(pageabLe);
}
select
boardO_.bno as bnol_0_,
boards..moddate as moddate2_0.
boardG_.regdate as regdate3_0.
board0_.content as content4_0.
boarde_.title as title5_0_,
board0_.writer as writer6_0_
from
board boardO_
order by
board0.bno desc limit ?
// โญ ๋ฐํํ์
์ ํ์ด์ง ๊ด๋ จ์ผ๋ก ๋ฐ์์ ๊ฒฝ์ฐ count(์ปฌ๋ผ) ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ค.
select
count(boardO_.bno) as col_0_0_
from
board boardO
findAll()
์ ๋ฆฌํด ํ์
์ผ๋ก ๋์ค๋ Page<T>
ํ์
์ ๋ด๋ถ์ ์ผ๋ก ํ์ด์ง ์ฒ๋ฆฌ์ ํ์ํ ์ฌ๋ฌ ์ ๋ณด๋ฅผ ์ฒ๋ฆฌํ๋ค. ์๋ฅผ ๋ค์ด ๋ค์ ํ์ด์ง ์กด์ฌ์ฌ๋ถ, ์ด์ ํ์ด์ง ์กด์ฌ์ฌ๋ถ, ์ ์ฒด ๋ฐ์ดํฐ ๊ฐ์ ๋ฑ์ ๊ธฐ๋ฅ์ ๋ชจ๋ ํ์ธํ ์ ์๋ค.// ๊ณผ๊ฑฐ์๋ Slice ์ธํฐํ์ด์ค๊ฐ ์๋ Iterable์ ์์๋ฐ์์๋ค.
// ํ์ฌ๋ Slice<T>๊ฐ Streamable<T>๋ฅผ ์์๋ฐ๊ณ , Streamable<T>๊ฐ Iterable<T>์ Supplier<Stream<T>>๋ฅผ ์์๋ฐ๋๋ค.
public interface Page<T> extends Slice<T> // Slice<T>
int getNumber(); //ํ์ฌ ํ์ด์ง
int getSize(); //ํ์ด์ง ํฌ๊ธฐ
int getTotalPages(); //์ ์ฒด ํ์ด์ง ์
int getNumberOfElements(); //ํ์ฌ ํ์ด์ง์ ๋์ฌ ๋ฐ์ดํฐ ์
long getTotalElements(); //์ ์ฒด ๋ฐ์ดํฐ ์
boolean hasPreviousPage(); //์ด์ ํ์ด์ง ์ฌ๋ถ
boolean isFirstPage(); //ํ์ฌ ํ์ด์ง๊ฐ ์ฒซ ํ์ด์ง ์ธ์ง ์ฌ๋ถ
boolean hasNextPage(); //๋ค์ ํ์ด์ง ์ฌ๋ถ
boolean isLastPage(); //ํ์ฌ ํ์ด์ง๊ฐ ๋ง์ง๋ง ํ์ด์ง ์ธ์ง ์ฌ๋ถ
Pageable nextPageable (); //๋ค์ ํ์ด์ง ๊ฐ์ฒด , ๋ค์ ํ์ด์ง๊ฐ ์์ผ๋ฉด null
Pageable previousPageable ();//๋ค์ ํ์ด์ง ๊ฐ์ฒด, ์ด์ ํ์ด์ง๊ฐ ์์ผ๋ฉด null
List<T> getContent(); //์กฐํ๋ ๋ฐ์ดํฐ
boolean hasContent(); //์กฐํ๋ ๋ฐ์ดํฐ ์กด์ฌ ์ฌ๋ถ
Sort getSort(); //์ ๋ ฌ ์ ๋ณด
Pageable๊ณผ Page๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ด์ง์ ์ฝ๊ฒ ๊ฐ๋ฐํ ์ ์๋ค.
โญ Page๋ฅผ ์ฌ์ฉํ๋ฉด ์คํ๋ง ๋ฐ์ดํฐ JPA๋ ํ์ด์ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ์ํด ๊ฒ์๋ ์ ์ฒด ๋ฐ์ดํฐ ๊ฑด์๋ฅผ ์กฐํํ๋ count ์ฟผ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ํธ์ถํ๋ค.
//count ์ฟผ๋ฆฌ ์ฌ์ฉ
Page<Member> findByName(String name, Pageable pageable);
//count ์ฟผ๋ฆฌ ์ฌ์ฉ ์ ํจ
List<Member> findByName (String name, Pageable pageable);
List<Member> findByName (String name, Sort sort);
Spring Domain ํด๋์ค ์ค org.springframework.data.domain.Sort
โญ ํด๋์ค๋ Spring Data ํ๋ก์ ํธ์์ DB ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ ฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ํด๋์ค์ด๋ค. Spring Data JPA๋ฅผ ๋น๋กฏํด ๋ค์ํ Spring Data ๋ชจ๋์์ ์ด ํด๋์ค๋ฅผ ํ์ฉํ์ฌ ์ ๋ ฌ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
Sort ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค:
- โ ์ ๋ ฌ ์์ฑ๊ณผ ๋ฐฉํฅ ์ค์ : Sort ๊ฐ์ฒด๋ ์ ๋ ฌ์ ์ฌ์ฉ๋ ์์ฑ๊ณผ ์ ๋ ฌ ๋ฐฉํฅ์ ์ง์ ํ ์ ์์ต๋๋ค. ์์ฑ์ ์ํฐํฐ์ ํ๋๋ฅผ ๋ํ๋ด๋ฉฐ, ๋ฐฉํฅ์ ์ค๋ฆ์ฐจ์(Ascending) ๋๋ ๋ด๋ฆผ์ฐจ์(Descending)์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค.
- โก๋ค์ค ์ ๋ ฌ: Sort ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ์์ฑ์ ๋ํด ๋ค์ค ์ ๋ ฌ์ ์ง์ ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ์ฒซ ๋ฒ์งธ ์์ฑ์ผ๋ก ์ ๋ ฌํ ํ, ๋์ผํ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ์ ๋ ๋ฒ์งธ ์์ฑ์ผ๋ก ์ ๋ ฌํ ์ ์์ต๋๋ค.
- โขํ์ด์ง๊ณผ ํจ๊ป ์ฌ์ฉ: Sort ๊ฐ์ฒด๋ Pageable๊ณผ ํจ๊ป ์ฌ์ฉํ์ฌ ํ์ด์ง๋ค์ด์ ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ ฌํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ํน์ ์์ฑ๊ณผ ๋ฐฉํฅ์ ๋ฐ๋ผ ํน์ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ์ฌ ๋ฐํํ ์ ์์ต๋๋ค.
import org.springframework.data.domain.Sort;
// ๋จ์ผ ์์ฑ์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ (name ์์ฑ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์)
Sort sort = Sort.by(Sort.Direction.ASC, "name");
// ๋จ์ผ ์์ฑ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌ (name ์์ฑ์ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ)
Sort sort = Sort.by(Sort.Order.desc("name"));
// ๋ค์ค ์์ฑ์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ (์ฒซ ๋ฒ์งธ ์์ฑ์ผ๋ก ์ ๋ ฌํ๊ณ , ๋์ผํ ๊ฐ์ด ์์ผ๋ฉด ๋ ๋ฒ์งธ ์์ฑ์ผ๋ก ์ ๋ ฌ)
Sort sort = Sort.by(Sort.Direction.ASC, "category").and(Sort.by(Sort.Direction.DESC, "price"));
// ๋ค์ค ์์ฑ์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ (category๋ก ๋จผ์ ์ ๋ ฌํ๊ณ , ๋์ผํ category ๋ด์์๋ price๋ก ์ ๋ ฌ)
Sort sort = Sort.by(Sort.Order.asc("category"), Sort.Order.asc("price"));
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
// ์ฒซ ๋ฒ์งธ ํ์ด์ง, ํ์ด์ง๋น 10๊ฐ์ ๊ฒฐ๊ณผ, category ์์ฑ์ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "category"));
// ๋ฆฌํฌ์งํ ๋ฆฌ ๋ฉ์๋์์ ์ฌ์ฉํ ์ ์๋ ์์
Page<MyEntity> result = myEntityRepository.findAll(pageable);
import org.springframework.data.jpa.repository.JpaRepository;
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> {
}
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> {
Page<YourEntity> findAll(Pageable pageable);
}
@Service
public class YourService {
@Autowired
private YourRepository yourRepository;
public Page<YourEntity> getEntities(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
return yourRepository.findAll(pageRequest);
}
// ๋ค๋ฅธ ๋น์ฆ๋์ค ๋ก์ง๋ค...
}
@RestController
public class YourController {
@Autowired
private YourService yourService;
@GetMapping("/entities")
public ResponseEntity<List<YourEntity>> getEntities(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Page<YourEntity> pageResult = yourService.getEntities(page, size);
List<YourEntity> entities = pageResult.getContent();
return new ResponseEntity<>(entities, HttpStatus.OK);
}
// ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ ๋ฉ์๋๋ค...
}
@Autowired
๋ฅผ ๋ถ์์ง๋ง, ์์ฑ์๋ฅผ ํตํ DI๋ฅผ ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
- GPT:
์์ฑ์ ์ธ์ ์ ์ ๋ช ์์ ์ธ ์์ฑ์๋ฅผ ํตํด ํ์ํ ์์กด์ฑ์ ์ฃผ์ ํ๊ธฐ ๋๋ฌธ์ ์์ฑ์์ @Autowired๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ ํ ์คํธ๋ฅผ ์ฉ์ดํ๊ฒ ํ๊ณ , ํด๋์ค์ ์์กด์ฑ์ ๋ช ํํ๊ฒ ํํํ์ฌ ์ฝ๋ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ๋ํ, ์์ฑ์ ์ธ์ ์ ์ ์ฌ์ฉํ๋ฉด ํด๋น ํด๋์ค์ ํ๋๋ค์ final๋ก ์ ์ธํ์ฌ ๋ถ๋ณ์ฑ์ ์ ์งํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ฝ๋ ์์ ์ฑ๊ณผ ํ์ง์ ๋์ด๋๋ฐ ๋์์ด ๋ฉ๋๋ค.
Controller ๋จ์์ ๋ฐ๋์ page, size๋ฅผ ๋ชจ๋ ๋ช
์์ ์ผ๋ก ๋ฐ์ ํ์๋ ์๋ค.
์ธ์๋ฅผ Pageable ํ์
์ผ๋ก ๋ฐ๋๋ค๋ฉด Spring Data JPA ๋ด๋ถ์์ ํด๋ผ์ด์ธํธ ์ธก์์ ์ ๋ฌ๋ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ?page=0&size=10
๋ฑ์ ์ธ์ํ์ฌ ๋ํ์
๊ฐ์ฒด๋ก ์์ฑํด์ค๋ค.
์ฐธ๊ณ ) ์ด์ ์ฝ๋ (@RequestParam
์ฌ์ฉ)
@Operation(summary = "Get All Member", description = "์ ์ฒด ๊ณ์ ์กฐํ ๊ธฐ๋ฅ")
@GetMapping
public ResponseEntity getAccounts(@Positive @RequestParam int page,
@Positive @RequestParam int size) {
Page<AccountPageResponseDto> accountsPage = accountService.findAccounts(page-1, size);
List<AccountPageResponseDto> accounts = accountsPage.getContent();
return new ResponseEntity<>(
new MultiResponseDto<>(HttpStatusCode.OK.getStatusCode(), HttpStatusCode.OK.getMessage(), accounts, accountsPage)
, HttpStatus.OK);
}
๋ง์ ๋์์ด ๋์์ต๋๋ค, ๊ฐ์ฌํฉ๋๋ค.