์คํ๋ง๋ถํธ ํ์ด์ง์ฒ๋ฆฌํ๊ธฐ(JPA + RESTAPI)
- -
๐ฅดPaging?
๊ธ ๋ชฉ๋ก์ด๋ ์ ์ ๋ชฉ๋ก ๋ฑ์ ๊ตฌํํ๋ค ๋ณด๋ฉด ํ์ด์ง์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋ค. ํ์ด์ง๋ฅผ ๋๋ ํด๋น ํ์ด์ง์ ํ์ํ ์ ๋ณด๋ง ๋ณด๋ด๊ธฐ๋ ํ๊ณ , ์ ๋ ฌ ๊ธฐ์ค์ด ํ์ํ ๊ฒฝ์ฐ๋ ์์ ๊ฒ์ด๋ค.
์คํ๋ง์์๋ ๊ฐํธํ๊ฒ๋ ํด๋น ๊ธฐ๋ฅ์ ๊ตฌํํ Page, Pageable์ด ์กด์ฌํ๋ค. ํ์ฌ ํ๋ก์ ํธ ๊ตฌํ ์ค์ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํด์ผ ํ๋ ๋ถ๋ถ์ด ์๊ฒจ์ ํด๋น ๊ธฐ๋ฅ์ ๊ฐ๋ตํ๊ฒ ์ ๋ฆฌํด ๋ณด๋ ค๊ณ ํ๋ค.
๐ฐ๏ธController
๋จผ์ ์ปจํธ๋กค๋ฌ์์์ Paging์ฒ๋ฆฌ์ด๋ค.
๋ณดํต ์์ฒญ์ ๋ค์๊ณผ ๊ฐ์ด Pageable์ page, size, sort 3๊ฐ์ง์ ํ๋ผ๋ฏธํฐ๋ก ์์ฒญ๋ฐ๋๋ค.
/api/admin/users?page=3&size=1&sort=id,DESC
→ 3๋ฒ์งธ ํ์ด์ง / ํ์ด์ง๋น ์ฌ์ด์ฆ 1 / id๊ธฐ์ค ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ
@GetMapping("api/admin/users")
public ResponseEntity<Map<String, Object>> readAllUser(Pageable pageable) {
Page<ReadUserInfoResponseDTO> responseDTO = userService.readAllUser(pageable);
Map<String, Object> result = new HashMap<>();
result.put("msg", "์ ์ฒด ์ ์ ์กฐํ๊ฐ ์๋ฃ๋์์ต๋๋ค.");
result.put("data", responseDTO);
return ResponseEntity.ok().body(result);
}
์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด @RequestBody ๋๋ @RequestParam ์์ด ๋จ๋ ์ผ๋ก Pageable๋ง ๋ค์ด๊ฐ ์๋๋ฐ,
์ด๋ ์์ฒญํ ๋, PageableHandlerMethodArgumentResolver ์์ Pageable ๊ฐ์ฒด๋ฅผ ํ์ธํ๊ณ ์ง์ ๋ณํํ์ฌ Pageable์ ๊ตฌํ ํด๋์ค์ธ PageRequest๋ฅผ ๋ฐํํ์ฌ ํ๋ผ๋ฏธํฐ์ ๋ฃ์ด์ค๋ค.(์๋ ์ฝ๋ ํ์ธ)
/*
* (non-Javadoc)
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return Pageable.class.equals(parameter.getParameterType());
}
/*
* (non-Javadoc)
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.method.support.ModelAndViewContainer, org.springframework.web.context.request.NativeWebRequest, org.springframework.web.bind.support.WebDataBinderFactory)
*/
@Override
public Pageable resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
String page = webRequest.getParameter(getParameterNameToUse(getPageParameterName(), methodParameter));
String pageSize = webRequest.getParameter(getParameterNameToUse(getSizeParameterName(), methodParameter));
Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
Pageable pageable = getPageable(methodParameter, page, pageSize);
if (sort.isSorted()) {
return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort);
}
return pageable;
}
๐คService
public Page<ReadUserInfoResponseDTO> readAllUser(Pageable pageable) {
Page<User> users = userRepository.findByDeleted(pageable, false);
return users.map(ReadUserInfoResponseDTO::toDTO);
}
ํ์ฌ ํ๋ก์ ํธ์์๋ ์๋น์ค๋จ์์ dto๋ณํ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ repository์์ ๋ฐ์์จ ๋ชฉ๋ก์ Page์ map๋ฉ์๋๋ฅผ ํตํด, dto๋ก ๋ณํํ์ฌ ๋ฐํํ๋ค.
๐ฆRepository
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
Page<User> findByDeleted(Pageable pageable, boolean deleted);
}
Jpa์์ Page๋ก ๋ฐ์์ค๋ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๊ณ ์๋ค. ์ค์ ๋ก ์ฟผ๋ฆฌ๋ก ๋ ๋ฆด ๋ 2๋ฒ์ ์์ฒญ์ด ๋๊ฐ๋๋ฐ, ํ ๋ฒ์ ์ ๋ ฌ๋ ๊ฐ์ฒด๋ค์ ๋ฐ์์ค๋ ์์ฒญ, ๋ค๋ฅธ ํ ๋ฒ์ ์ ์ฒด ํ์ด์ง๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํ count ๋ฉ์๋๊ฐ ์คํ๋๋ค.
spring.jpa.show-sql=true ํ์ ๋, ๋ณผ ์ ์๋ ์ฟผ๋ฆฌ)
Hibernate:
select
user0_.user_id as user_id1_11_,
user0_.created_date as created_2_11_,
user0_.modified_date as modified3_11_,
user0_.deleted as deleted4_11_,
user0_.email as email5_11_,
user0_.github_id as github_i6_11_,
user0_.phone_number as phone_nu7_11_,
user0_.profile_img_url as profile_8_11_,
user0_.role as role9_11_,
user0_.username as usernam10_11_
from
user user0_
where user0_.deleted=?
order by user0_.user_id desc limit ?,
?
Hibernate:
select
count(user0_.user_id) as col_0_0_
from user user0_
where user0_.deleted=?
๐ฆฟ๊ธฐ๋ณธ ํ๋ผ๋ฏธํฐ ์ค์ ํ๊ธฐ
์์ ๊ฐ์ ํ์์ผ๋ก ์คํ๋ง ๋ถํธ๋ก ํ์ด์ง์ ๊ตฌํํ ์ ์์ผ๋ฉฐ, pageableํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ์ง ์๋๋ผ๋ ๊ธฐ๋ณธ ๊ฐ์ ๋ณ๊ฒฝํจ์ผ๋ก์จ ๋ํ๋ด ์ฃผ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
@GetMapping("api/admin/users")
public ResponseEntity<Map<String, Object>> readAllUser(
@PageDefault(size=100, sort="id", direction = Sort.Direction.DESC) Pageable pageable) {
Page<ReadUserInfoResponseDTO> responseDTO = userService.readAllUser(pageable);
Map<String, Object> result = new HashMap<>();
result.put("msg", "์ ์ฒด ์ ์ ์กฐํ๊ฐ ์๋ฃ๋์์ต๋๋ค.");
result.put("data", responseDTO);
return ResponseEntity.ok().body(result);
}
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ฐ์ํ ๊ฐ์ฒด์งํฅ [์ฐ์ํํ ํฌ์ธ๋ฏธ๋] ์ ๋ฆฌ 4 (1) | 2023.11.08 |
---|---|
์ฐ์ํ ๊ฐ์ฒด์งํฅ [์ฐ์ํํ ํฌ์ธ๋ฏธ๋] ์ ๋ฆฌ 3 (0) | 2023.11.07 |
์ฐ์ํ ๊ฐ์ฒด์งํฅ [์ฐ์ํํ ํฌ์ธ๋ฏธ๋] ์ ๋ฆฌ 2 (0) | 2023.11.07 |
์ฐ์ํ ๊ฐ์ฒด์งํฅ [์ฐ์ํํ ํฌ์ธ๋ฏธ๋] ์ ๋ฆฌ 1 (0) | 2023.11.07 |
SLF4J + Log4j2 ์ค์ ํด๋ณด๊ธฐ (0) | 2023.07.05 |
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค