# [JPA] Spring Data JPA - Web ํ™•์žฅ ๊ธฐ๋Šฅ
Study Repository

[JPA] Spring Data JPA - Web ํ™•์žฅ ๊ธฐ๋Šฅ

by rlaehddnd0422

Spring Data JPA๋Š” MVC์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

๋„๋ฉ”์ธ ํด๋ž˜์Šค ์ปจ๋ฒ„ํ„ฐ ๊ธฐ๋Šฅ

๋„๋ฉ”์ธ ํด๋ž˜์Šค ์ปจ๋ฒ„ํ„ฐ๋Š” HTTP ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ ์—”ํ‹ฐํ‹ฐ์˜ ์•„์ด๋””๋กœ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„์„œ ๋ฐ”์ธ๋”ฉํ•ด์ค๋‹ˆ๋‹ค.

 

๊ธฐ์กด์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์‹๋ณ„์ž๋ฅผ Service๊ณ„์ธต์ด๋‚˜ Repository๊ณ„์ธต์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ฐพ๊ฒŒ ํ–ˆ์ง€๋งŒ,

@GetMapping("/members/{id}")
@ResponseBody
public String findMember(@PathVariable("id") Long id){
	return memberRepository.findById(id).getName()
}

Spirng Data JPA๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋„๋ฉ”์ธ ํด๋ž˜์Šค ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‹๋ณ„์ž๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„ ์—”ํ‹ฐํ‹ฐ์˜ ์•„์ด๋””๋กœ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„์„œ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@GetMapping("/members/{id}")
public String findMember(@PathVariable("id") Member member) {
    return member.getName();
}

์ฃผ์˜ํ•  ์  : ํŠธ๋žœ์žญ์…˜์ด ์—†๋Š” ๋ฒ”์œ„์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ DB์— ๋ฐ˜์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

๋”ฐ๋ผ์„œ ์ด ๊ธฐ๋Šฅ์€ ๋‹จ์ˆœํžˆ ์กฐํšŒ์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŽ˜์ด์ง• ๋ฐ ์ •๋ ฌ ๊ธฐ๋Šฅ

์Šคํ”„๋ง ๋ฐ์ดํ„ฐ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํŽ˜์ด์ง•๊ณผ ์ •๋ ฌ ๊ธฐ๋Šฅ์„ MVC์—์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก HandlerMethodArgumentResolver๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ํŽ˜์ด์ง• ๊ธฐ๋Šฅ : PageableHandlerMethodArgumentResolver
  • ์ •๋ ฌ ๊ธฐ๋Šฅ : SortHandlerMethodArgumentResolver
@GetMapping("/members")
public Page<Member> list(Pageable pageable, Model model){
	
   Page<Member> page = memberRepository.findAll(pageable);
   return page;
}

HandlerMethodArgumentResolver๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Pageable์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ

  • page : ํ˜„์žฌ ํŽ˜์ด์ง€, 0๋ถ€ํ„ฐ ์‹œ์ž‘
  • size : ํ•œ ํŽ˜์ด์ง€์— ๋…ธ์ถœํ•  ๋ฐ์ดํ„ฐ ๊ฑด์ˆ˜
  • sort : ์ •๋ ฌ ์กฐ๊ฑด ์ •์˜ 

ex) /members?page=0&size=3&sort=id,desc&sort=username,desc

 

์ถ”๊ฐ€1 : ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด ๋””ํดํŠธ ๊ฐ’์„ application.properties์— ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

spring.data.web.pageable.default-page-size=20 /# ๊ธฐ๋ณธ ํŽ˜์ด์ง€ ์‚ฌ์ด์ฆˆ/ 
spring.data.web.pageable.max-page-size=2000 /# ์ตœ๋Œ€ ํŽ˜์ด์ง€ ์‚ฌ์ด์ฆˆ/

์ถ”๊ฐ€1-1 : ๊ฐœ๋ณ„์„ค์ •์€ @PageableDefulat ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ

public String list(@PageableDefault(size = 12, sort = “username”,
				direction = Sort.Direction.DESC) Pageable pageable) {
	... 
}

์ถ”๊ฐ€ 2 : ํŽ˜์ด์ง• ์ •๋ณด๊ฐ€ ๋‘˜ ์ด์ƒ์ธ ๊ฒฝ์šฐ - ์ด ๋•Œ @Qualifier์— ์ ‘๋‘์‚ฌ๋ช…์„ ์ถ”๊ฐ€ํ•ด ์ถ”๊ฐ€ ๊ตฌ๋ถ„์ž๋ฅผ ๋“ฑ๋กํ•ด ์ค์‹œ๋‹ค.

 

Spring / @Qualifier, @Primary

๋“ฑ๋ก๋œ ๋นˆ์ด 2๊ฐœ ์ด์ƒ์ผ ๋•Œ @Component public class FixDiscountPolicy implements DiscountPolicy{ @Component public class RateDiscountPolicy implements DiscountPolicy{ ์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์กฐํšŒ ๋นˆ์ด 2๊ฐœ ์ด์ƒ ๋“ฑ๋ก๋œ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€

rlaehddnd0422.tistory.com

@GetMapping("/members")
public String list(
	@Qualifier("member") Pageable memberPageable,
    @Qualifier("order") Pageable orderPageable, ...){
	...
}

ex) /members?member_page=0&order_page=1&member_size=5&order_size=3

 

์ถ”๊ฐ€ 3 : ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์–ธ์ œ๋‚˜ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง•์„ ์‚ฌ์šฉํ•  ๋•Œ ๋˜ํ•œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœํ•˜์ง€ ๋ง๊ณ  DTO๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค !

Page๋Š” map()์„ ์ง€์›ํ•ด์„œ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@GetMapping("/members")
  public Page<MemberDto> list(Pageable pageable) {
      Page<Member> page = memberRepository.findAll(pageable);
      Page<MemberDto> pageDto = page.map(MemberDto::new);
      return pageDto;
}

์ถ”๊ฐ€ 4 : ํŽ˜์ด์ง€๋ฅผ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ณ  ์‹ถ์œผ๋ฉด PageableHandlerMethodArgumentResolver๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ์ง์ ‘ ๋“ฑ๋กํ•œ ์ดํ›„ setOneIndexedParameters๋ฅผ true๋กœ ์„ค์ •

@Configuration
public class CustomPageableConfiguration {
    @Bean
    public PageableHandlerMethodArgumentResolverCustomizer customize() {
        return p -> p.setOneIndexedParameters(true);
    }
}

๋˜๋Š” application.properties์— ์„ค์ • ์ถ”๊ฐ€ 

spring.data.web.pageable.one-indexed-parameters=true
์ด ๋ฐฉ๋ฒ•๋“ค์€ web์—์„œ page ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ -1 ์ฒ˜๋ฆฌํ•  ๋ฟ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋ผ์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋‚˜ ๋ฉ”์†Œ๋“œ๋ฅผ๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ๋ฐ›๋Š” ๊ฐ’๊ณผ -1์”ฉ ์ฐจ์ด๊ฐ€ ๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ํŽ˜์ด์ง€ index๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅ ๊ฐ’์— -1์„ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

 

<์ฐธ๊ณ  ์ž๋ฃŒ>

 

์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MVC 2ํŽธ์—์„œ๋Š” MVC 1ํŽธ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ ๊ตฌ์กฐ ์œ„์— ์‹ค๋ฌด ์›น ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ํ™œ์šฉ ๊ธฐ์ˆ ๋“ค์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ

www.inflearn.com

 

 

Spring Data JPA์˜ Slice & Page

์ด ๊ธ€์€ ์šฐํ…Œ์ฝ” ๋‹ฌ๋กํŒ€ ํฌ๋ฃจ ํŒŒ๋ž‘์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. Spring Data JPA์—์„œ๋Š” Pagination์„ ์œ„ํ•œ ๋‘ ๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋ฐ”๋กœ Slice์™€ Page๋‹ค. Repository ์ฝ”๋“œ๋ฅผ ๋จผ์ € ๋ณด์ž. ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ์ฒด๋ฅผ

dallog.github.io

 

 

Spring Data JPA์—์„œ์˜ ํŽ˜์ด์ง€๋„ค์ด์…˜๊ณผ ์ •๋ ฌ

ํŽ˜์ด์ง€๋„ค์ด์…˜ (Pagination) ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ–ˆ์„ ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ๋Š” ์ˆ˜์ฒœ, ์ˆ˜๋งŒ, ์ˆ˜๋ฐฑ๋งŒ ์ค„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์กฐํšŒํ•˜์—ฌ ์ œ๊ณตํ•œ๋‹ค๋ฉด ์„œ๋ฒ„์˜ ๋ถ€ํ•˜๊ฐ€ ๊ต‰์žฅํžˆ ํด ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋Œ€๋ถ€

hudi.blog

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ