Skip to content

[๐ŸŒฑ JPA ๋ฐฉํƒˆ์ถœ ์˜ˆ์•ฝ ๋Œ€๊ธฐ] ๊ณ ๋ž˜ ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค.#590

Open
miniminjae92 wants to merge 5 commits into
woowacourse:miniminjae92from
miniminjae92:jpa-migration
Open

[๐ŸŒฑ JPA ๋ฐฉํƒˆ์ถœ ์˜ˆ์•ฝ ๋Œ€๊ธฐ] ๊ณ ๋ž˜ ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค.#590
miniminjae92 wants to merge 5 commits into
woowacourse:miniminjae92from
miniminjae92:jpa-migration

Conversation

@miniminjae92

@miniminjae92 miniminjae92 commented Jun 18, 2026

Copy link
Copy Markdown

๋‹จ๊ณ„๋ณ„ ๋„๋‹ฌ ์ง€์ 

์‚ฌ์ „ ์„ค๋ฌธ

  • JPA๋ฅผ ์ฒ˜์Œ ๋‹ค๋ฃจ๋Š” ์ƒํƒœ์—์„œ ์ถœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฒˆ ๋ฏธ์…˜ ๋ชฉํ‘œ๋Š” JPA๊ฐ€ ๋ฌด์—‡์„ ์ž๋™ํ™”ํ•˜๊ณ , ์™œ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ฒด๊ฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์ „ํ•™์Šต

  • JDBC, JdbcTemplate, JPA์˜ ์—ญํ•  ์ฐจ์ด๋ฅผ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ, LAZY, fetch join, EntityGraph, JPQL์„ ์ด๋ฒˆ ๋ฏธ์…˜ ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐํ•ด ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค.

0๋‹จ๊ณ„

  • ๊ธฐ์กด ๋ฐฉํƒˆ์ถœ ๋ฏธ์…˜ ์ฝ”๋“œ ์œ„์—์„œ JPA ์ „ํ™˜์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Controller, Service์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ๋ฆ„์€ ์ตœ๋Œ€ํ•œ ์œ ์ง€ํ•˜๊ณ  Repository์™€ SQL ์ค‘์‹ฌ ์ฝ”๋“œ๋ฅผ ์ „ํ™˜ ๋Œ€์ƒ์œผ๋กœ ์žก์•˜์Šต๋‹ˆ๋‹ค.

1๋‹จ๊ณ„

  • JdbcTemplate ๊ธฐ๋ฐ˜ Repository๋ฅผ Spring Data JPA Repository๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Reservation, ReservationDate, ReservationTime, Theme๋ฅผ JPA ์—”ํ‹ฐํ‹ฐ๋กœ ๋งคํ•‘ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Reservation์ด ๋‚ ์งœ, ์‹œ๊ฐ„, ํ…Œ๋งˆ๋ฅผ ๊ฐ์ฒด ์ฐธ์กฐ๋กœ ๊ฐ€์ง€๋„๋ก @ManyToOne(fetch = LAZY) ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ dirty checking, 1์ฐจ ์บ์‹œ, ์“ฐ๊ธฐ ์ง€์—ฐ, flush ์‹œ์ , LAZY ์ ‘๊ทผ์„ ๊ด€์ฐฐํ–ˆ์Šต๋‹ˆ๋‹ค.

2๋‹จ๊ณ„

  • ๋‚ด ์˜ˆ์•ฝ ๋ชฉ๋ก ์กฐํšŒ๋ฅผ JPQL + @EntityGraph๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์œ ํšจ ์˜ˆ์•ฝ ์กฐ๊ฑด์€ JPQL๋กœ ํ‘œํ˜„ํ•˜๊ณ , DTO ์ƒ์„ฑ์— ํ•„์š”ํ•œ date, time, theme๋Š” EntityGraph๋กœ ํ•จ๊ป˜ ๋กœ๋”ฉํ–ˆ์Šต๋‹ˆ๋‹ค.

3๋‹จ๊ณ„

  • WaitingReservation์„ JPA ์—”ํ‹ฐํ‹ฐ๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ์กด JDBC ์˜ˆ์•ฝ ๋Œ€๊ธฐ Repository ๊ตฌํ˜„์ฒด๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์•ฝ ๋Œ€๊ธฐ ์ˆœ๋ฒˆ์€ JPQL์˜ count + 1 ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ ๊ณ„์‚ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
  • N+1 ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์˜ˆ์•ฝ ๋Œ€๊ธฐ ์กฐํšŒ์—๋„ @EntityGraph๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

4๋‹จ๊ณ„

  • ์˜ˆ์•ฝ ์ทจ์†Œ/์ˆ˜์ • ์‹œ ๊ฐ™์€ ์Šฌ๋กฏ์˜ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์˜ˆ์•ฝ ๋Œ€๊ธฐ๋ฅผ ์ž๋™ ์Šน๊ฒฉํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ˜„์žฌ๋Š” ReservationService์˜ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์˜ˆ์•ฝ ์‚ญ์ œ, ๋Œ€๊ธฐ ์กฐํšŒ, ์˜ˆ์•ฝ ์ƒ์„ฑ, ์Šน๊ฒฉ๋œ ๋Œ€๊ธฐ ์‚ญ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋ฐœํ–‰ SQL ๋ฐœ์ทŒ

์˜ˆ์•ฝ ๋Œ€๊ธฐ ์ˆœ๋ฒˆ ๊ณ„์‚ฐ JPQL์€ ์•„๋ž˜์™€ ๊ฐ™์€ SQL๋กœ ๋ณ€ํ™˜๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

select
wr1_0.id,
wr1_0.created_at,
d3_0.id,
d3_0.play_day,
wr1_0.name,
t5_0.id,
t5_0.content,
t5_0.name,
t5_0.url,
t6_0.id,
t6_0.start_at,
(select
(count(wr2_0.id)+1)
from
waiting_reservation wr2_0
where
wr2_0.date_id=wr1_0.date_id
and wr2_0.time_id=wr1_0.time_id
and wr2_0.theme_id=wr1_0.theme_id
and (
wr2_0.created_at<wr1_0.created_at
or (wr2_0.created_at=wr1_0.created_at and wr2_0.id<wr1_0.id)
))
from
waiting_reservation wr1_0
join reservation_date d3_0 on d3_0.id=wr1_0.date_id
left join theme t5_0 on t5_0.id=wr1_0.theme_id
join reservation_time t6_0 on t6_0.id=wr1_0.time_id
where
wr1_0.name=?
order by
d3_0.play_day,
t6_0.start_at,
wr1_0.id

๋ง์„ค์ธ ๊ฒฐ์ •

  • ๋ณต์žกํ•œ ์กฐํšŒ ์กฐ๊ฑด์€ ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์ฟผ๋ฆฌ๋ณด๋‹ค JPQL์ด ๋” ์ ์ ˆํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.
  • N+1 ํ•ด๊ฒฐ์€ join fetch ๋Œ€์‹  @EntityGraph๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์กฐ๊ฑด๊ณผ ๋กœ๋”ฉ ๋ฒ”์œ„๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์ฝ๋Š” ํŽธ์ด ๋” ๋ช…ํ™•ํ•˜๋‹ค๊ณ  ๋ดค์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์•ฝ ๋Œ€๊ธฐ๋ฅผ Reservation.status๋กœ ํ†ตํ•ฉํ• ์ง€, ๋ณ„๋„ WaitingReservation์œผ๋กœ ์œ ์ง€ํ• ์ง€ ๊ณ ๋ฏผํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์š”๊ตฌ์‚ฌํ•ญ๋งŒ ๋ณด๋ฉด status๋„ ๊ฐ€๋Šฅํ•ด ๋ณด์˜€์ง€๋งŒ, ์ด๋ฒˆ ๊ตฌํ˜„์—์„œ๋Š” ์œ ๋‹ˆํฌ ์ œ์•ฝ ์ฐจ์ด๋ฅผ ๊ธฐ์ค€
    ์œผ๋กœ ๋ณ„๋„ ๋„๋ฉ”์ธ์„ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ”๋“ค๋ฆฐ ์ง€์ 

์ž๋™ ์Šน๊ฒฉ์„ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์— ๋ฌถ๋Š” ๋ฐฉ์‹์ด ํ•ญ์ƒ ์ข‹์€์ง€๋Š” ํ™•์‹ ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฐฉ์‹์€ ๋‹จ์ˆœํ•˜๊ณ  DB ์ผ๊ด€์„ฑ์€ ์ง€ํ‚ค๊ธฐ ์‰ฝ์ง€๋งŒ, ์Šน๊ฒฉ ์‹คํŒจ๊ฐ€ ์˜ˆ์•ฝ ์ทจ์†Œ ์‹คํŒจ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๊ณ  ๋™์‹œ์„ฑ ์ƒํ™ฉ๋„
์ถฉ๋ถ„ํžˆ ๋ฐฉ์–ดํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ์ด๋ฒคํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์ƒ๊ฐํ•ด๋ดค์ง€๋งŒ, ์ค‘๊ฐ„ ์ƒํƒœ, ์žฌ์‹œ๋„, ์ค‘๋ณต ์Šน๊ฒฉ, ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์•„์ง ๋ช…ํ™•ํžˆ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•ด ์ด๋ฒˆ ๋‹จ๊ณ„์—์„œ๋Š” ๋‹จ์ˆœํ•œ ํŠธ๋žœ์žญ์…˜ ๋ฐฉ์‹์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

@miniminjae92 miniminjae92 changed the title [0๋‹จ๊ณ„] ๊ธฐ๋ณธ ์ฝ”๋“œ ์ค€๋น„ํ•˜๊ธฐ [๐ŸŒฑ JPA ๋ฐฉํƒˆ์ถœ ์˜ˆ์•ฝ ๋Œ€๊ธฐ] ๊ณ ๋ž˜ ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant