2024. 11. 22. 09:10ใSpring/QueryDSL
๐๏ธ- github ์ฐธ๊ณ
https://github.com/kuk1157/spring-plus/commit/bc94468b00c609b9e8b2abeefcb6563077cae77a
๐ - ์ ์ฒดํ๋ฆ
์๊ตฌ์ฌํญ)
- ์ ๋ชฉ, ๋ด๋น์์ ๋๋ค์, ์์&์ข ๋ฃ์ผ(์์ฑ์ผ๊ธฐ์ค) ๊ฒ์ ๊ฐ๋ฅํ๋๋ก
- ์ ๋ชฉ๊ณผ ๋ด๋น์์ ๋๋ค์์ ๋ถ๋ถ์ ์ผ๋ก ์ผ์นํด๋ ๊ฒ์๋๋๋ก
- ์ผ์ ์ ์ ๋ชฉ, ๋ด๋น์์ ์, ๋๊ธ์ ์๋ฅผ ์กฐํ / ๊ฒ์ ๊ฒฐ๊ณผ๋ ํ์ด์ง ์ฒ๋ฆฌ๋๋๋ก ๋ฐํ
1) APIํ๊ฐ ์๋ก์์ฑ
2) ์ ๋ชฉ, ๋๋ค์, ์์&์ข
๋ฃ์ผ @RequestParam์ผ๋ก ๋๊ธฐ๊ธฐ
3) ๊ฒ์ ์ค์ ๊ณผ ๊ด๋ จ๋ ์ํ ์ฟผ๋ฆฌ๋ฌธ ์์ฑํด์ ์กฐํ(์ ์์ ์ผ๋ก ๊ฒ์๋๋๊ฑฐ ํ์ธ์๋ฃ)
4) ์ด๋ฏธ ๋ง๋ค์ด๋ TodoRepositoryCustom๊ณผ TodoRepositoryImpl์์ ๋ฏธ๋ฆฌ์์ฑํ ์ฟผ๋ฆฌ๋ฌธ์ QueryDSL๋ก ๋ฐ๊ฟ ์ฟผ๋ฆฌ๋ฉ์๋๋ฅผ ์ธํ
ํ๋ค.
5) QueryDSL์์ Projections ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํ์ํ ๊ฐ๋ง ๋ฐํ์ํฌ DTO๋ฅผ ๋ฐ๋ก๋ง๋ ๋ค
6) DTO์์ ์๊ตฌ์ฌํญ์ ๋ง๊ฒ ์ ๋ชฉ,๋ด๋น์์,๋๊ธ์๋ง ๋ฐํ์ํจ๋ค(id ๊ณ ์ ๋ฒํธ๋ง ์ถ๊ฐ๋ก ๋ด์๋ค.)
7) ๋ฐํํ์
์ controller, service, custom, impl์ ์ ๋ถ dto๋ก ๋ณ๊ฒฝํด์ค๋ค.
8) TodoRepositoryImpl์์ ์ํ์ฟผ๋ฆฌ๋ฌธ์ QueryDSL๋ก ๋ณ๊ฒฝํด์ค๋ค.
9) QueryDSL๋ณ๊ฒฝ ์๋ฃ ํ Postman ํ ์คํธ ํ๊ธฐ
๐ ๏ธ - QueryDSL ์ ์ฉ
QueryDSL๋ก ๋ฐ๊ฟ ์ฟผ๋ฆฌ)
- ์ผ์ ํ ์ด๋ธ์์ ๋๊ธ,๋ด๋น์ํ ์ด๋ธ๊ณผ joinํด์ ๋ด๋น์์์ ๋๊ธ์๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ๋ฌธ์ด๋ค.
- WHERE, AND์ ์ ์๊ตฌ์ฌํญ์ ๊ฒ์๊ธฐ๋ฅ์ผ๋ก ๋ค์ด๊ฐ๋ ๋ถ๋ถ๋ค์ด๋ค
โป (์ผ์ ์ ๋ชฉ, ๋ด๋น์์ ๋๋ค์, ์ผ์ ์์ฑ์ผ ์์&์ข ๋ฃ์ผ๋ก ๊ฒ์)
- GROUP BY 1,2๋ ๊ฐ ๋ฐ์ดํฐ๋ง๋ค ๋ด๋น์์์, ๋๊ธ ์๋ฅผ ์ถ์ถํ๊ธฐ ์ํด COUNT()์ ์ฌ์ฉํ์ง์๋ ์ปฌ๋ผ๋ค์ GROUP BY
- ์์ฑ์ผ๋ก ๋ด๋ฆผ์ฐจ์ํ์ฌ ์ ๋ ฌํด์ค๋ค.
- COUNT, JOIN, LIKE, ์๋ธ์ฟผ๋ฆฌ, BETWEEN, GROUP BY ์ ๋ง์ ํจ์์ ์กฐ๊ฑด์ด ๋ค์ด๊ฐ๊ณ ๋ชจ๋ QueryDSL๋ก ๋ณ๊ฒฝํด์ผํ๋ค.
1. controller - TodoController
- ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํด์ผํ๊ธฐ ๋๋ฌธ์ Page ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ค๋ค.
- TodoSearch DTO๋ฅผ ๋ฐํํ์ ์ผ๋ก ํด์ ๋ฉ์๋๋ฅผ ์์ฑํ๋ค.
- ๊ฒ์ ํญ๋ชฉ 4๊ฐ(์ ๋ชฉ,๋๋ค์, ์์์ผ, ์ข ๋ฃ์ผ) @RequestParam์ผ๋ก ๊ฐ์ ๋ด์์ค๋ค.
2. DTO - TodoSearch
- ์กฐํํ์๋ ํ์ํ ์ ๋ณด๋ค๋ง ๋ด์ DTOํ์ผ์ด๋ค.
- ์ผ์ ๊ณ ์ ๋ฒํธ๋ ์๊ตฌ์ฌํญ์๋ ์์์ง๋ง ๋ฐ์ดํฐ ํ์ธ์ฉ์ผ๋ก ์์๋ก ์ถ๊ฐํ์๋ค.
3. custom - TodoRepositoryCustom
- findTodoWithCommentAndManagerCounts๋ก ์ฟผ๋ฆฌ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ , ํ์ํ ๋งค๊ฐ๋ณ์๋ฅผ ๋ค ๋ด์์ค๋ค.
- TodoSearch DTO๋ฅผ ๋ฐํํ์ ์ผ๋ก ๋๋ค.
4. Impl - TodoRepositoryImpl
- ์ฝ๋๊ฐ ๊ธธ์ด์ ์บก์ณ๋ณธ 2๊ฐ
- ์ ์ฒด ์ฝ๋ ํ์ธ
- ์ฟผ๋ฆฌ๋ฌธ์์ ์ฌ์ฉํ Qํด๋์ค ๊ฐ์ฒด ์ธํ ์๋ธ์ฟผ๋ฆฌ ๋ฐ ํ ์ฟผ๋ฆฌ์์ ์ด 4๊ฐ์ ํ ์ด๋ธ์ ์ฐธ์กฐํด์ผํจ
- ์์์๋ถํฐ ์์๋๋ก ์ผ์ , ๋๊ธ, ๋ด๋น์, ์ ์ 4๊ฐ ๊ฐ์ฒด๋ฅผ ์ธํ
- String์ผ๋ก ๋ฐ์ start,end(์์&์ข ๋ฃ์ผ)๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ์ ๊ณผ ๋์ผํ๊ฒ ๋ง์ถ๋์ฝ๋
- ์์์ ์ง์ ์์ฑํ๋ ์ฟผ๋ฆฌ๋ฌธ์ QueryDSL๋ก ๋ณ๊ฒฝํ๊ฒ์ด๋ค.
1) JPAQuery ์ค์ ์ฟผ๋ฆฌ์ ์คํ์ ๋ด๋น / queryFactory๋ QueryDSL ์ฒ์ ์ฌ์ฉํ ๋ ์ธํ ํ๋ config์ด๋ค.
์ฐธ๊ณ - https://kuk1938.tistory.com/213
2) Projections๋ฅผ ํ์ฉํ๋ฉด ๋ณ๋์ DTOํ์ผ์ ๋ฐ์์ ์ฒ๋ฆฌํ ์ ์๋ค.
3) Projections.constructor์ ์ฌ์ฉํ์ฌ TodoSearch ํด๋์ค ํ์ผ์ ์์ฑ์์ ์กฐํํ๋ ค๋ ์ปฌ๋ผ๋ค์ ๋งคํํ๋ ๊ฒ์ด๋ค.
- TodoSearch์์ ๊ณ ์ ๋ฒํธ,์ ๋ชฉ,๋๊ธ์,๋ด๋น์์์ ์ผ์นํ๊ฒ 4๊ฐ๋ฅผ ๋งคํํ๋๊ฒ์ ๋ณผ ์ ์๋ค.
- ๋ด๋น์์์ ๋๊ธ์๋ ์์์ ์์ฑํ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํด์ ํด๋น ๊ฐ์ฒด์ id(๊ณ ์ ๋ฒํธ)๋ก COUNT() ํ๊ณ ์๋ค.
- ์ํ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋์ผํ๋ค๋ ๋ป์ด๋ค.
4) from()์์๋ ์กฐํํ ํ ์ด๋ธ๋ช (์ํฐํฐ)์ ์ ๋ ฅํ์ฌ ์กฐํํด์ค๋ค.
5) lefJoin์ ํ์ฉํ์ฌ ์ฐธ์กฐํ ํ ์ด๋ธ(์ํฐํฐ)์ ์ ํ๊ณ on()์ผ๋ก ์ด์ด์ค ์ปฌ๋ผ์ ์ธํ ํ๋ค.
- comment ํ ์ด๋ธ์ ์ฐธ์กฐ, comment์ todo_id์ todoํ ์ด๋ธ์ id(๊ณ ์ ๋ฒํธ)๋ฅผ ์ด์ด์ค๋ค๋ ๋ป์ด๋ค.(๋๊ธ&์ผ์ )
- manager ํ ์ด๋ธ์ ์ฐธ์กฐ, manager์ todo_id์ todoํ ์ด๋ธ์ id(๊ณ ์ ๋ฒํธ)๋ฅผ ์ด์ด์ค๋ค๋ ๋ป์ด๋ค.(๋ด๋น์&์ผ์ )
6) where()์ ๊ฒ์ํด์ผํ ๋ชจ๋ ํญ๋ชฉ์ ๋ฃ์ด์ค๋ค.
- ์ผ์ ์ ์ ๋ชฉ์ like๊ฒ์ํด์ผํ๊ธฐ ๋๋ฌธ์ todo.title.contains(title)์ ์ฌ์ฉํ์ฌ ๋งค๊ฐ๋ณ์(title)์ ๋ถ๋ถ์ผ์นํ๋์ง ํ์ธ.
7) and() ๋ด๋น์์ ๋๋ค์์ ์กฐํํด์ผํ๊ธฐ๋๋ฌธ์ ์๋ธ์ฟผ๋ฆฌ๊ฐ ํ์ํ๋ค.
- todoํ ์ด๋ธ์ user_id๋ฅผ userํ ์ด๋ธ์ id(๊ณ ์ ๋ฒํธ)๋ฅผ nickname์ ๋ถ๋ถ์ผ์นํ๋ id๋ฅผ ๊ตฌํด์ ์๋ก ๊ฐ์์ง ๋น๊ต
- todo.user.id.eq( JPAExpressions.select(user.id) ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํด user_id๋ฅผ ํ์ธํ๋ค๋ ๋ป
- from(user) .where(user.nickName.contains(nickName)) userํ ์ด๋ธ์ ๋๋ค์์ like๋ฌธ์ผ๋ก ๊ฒ์ํด์ ๋ถ๋ถ์ผ์น ํ์ธ
8) ์์ฑ์ผ ๊ธฐ์ค์ผ๋ก ์์์ผ&์ข ๋ฃ์ผ BETWEEN ๊ฒ์
- and(todo.createdAt.between(startDateTime, endDateTime))
- ์์์ ๋ ์ง ํ์์ผ๋ก ๋ณ๊ฒฝํ startDateTime, endDateTime๋ฅผ ํ์ฉ
9) ์ผ์ ๊ฐ ๋ฐ์ดํฐ๋ง๋ค ๋ด๋น์ ์์ ๋๊ธ ์๋ฅผ ์ง๊ณํด์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด GROUP BY ์งํ
- groupBy(todo.id, todo.title) id(์ผ์ ๊ณ ์ ๋ฒํธ)์ titile(์ผ์ ์ ๋ชฉ)์ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํ
10) ์์ฑ์ผ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ - ๊ฐ์ฅ ์ต๊ทผ์ ์์ฑ๋ Todo๊ฐ ๋จผ์ ์กฐํ๋๋๋ก
- orderBy(todo.createdAt.desc())
1) fetchCount() - ์ฟผ๋ฆฌ์์ ์ ์ฒด ๊ฑด์๋ฅผ ๊ตฌํด์จ๋ค.(ํ์ด์ง์ ํ์ฉ)
2) offset(pageable.getOffset()) - ํ์ฌ ํ์ด์ง์์ ์์ํ ํญ๋ชฉ์ ์์น
3) limit(pageable.getPageSize()) - ํ ํ์ด์ง์ ํ์ํ ํญ๋ชฉ์ ์
4) fetch() - ์ฟผ๋ฆฌ๋ฅผ ์คํํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ
5) return new PageImpl<>(results, pageable, total)
- PageImpl์ Page์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ํด๋์ค, ๊ฒฐ๊ณผ ๋ฆฌ์คํธ์ ํ์ด์ง ์ ๋ณด๋ฅผ ๋ฐํํ ์ ์์.
- results : fetch() ๋ฉ์๋์์ ๊ฐ์ ธ์จ ํ์ฌ ํ์ด์ง์ TodoSearch ๋ชฉ๋ก
- pageable: ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ํ์ด์ง ์ ๋ณด์ ๋๋ค.
- total: ์ ์ฒด ๋ฐ์ดํฐ ์์ ๋๋ค.
5. Service - TodoService
- Controller์์ ์์ฑํ ๊ทธ๋๋ก ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๊ณ , ํ์ด์ง์ Pageable ๊ฐ์ฒด๋ฅผ ์ต์๋จ์ ๋จผ์ ์ธํ ํ๋ค.
- ๊ฐ ๊ฒ์๊ฐ์ ๋ํ ์์ธ์ฒ๋ฆฌ๋ฅผ ์งํํด๋๋ค. ๊ฐ ๊ฒ์์ ๋ํ 1๊ฐ,2๊ฐ,3๊ฐ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ค ์ก๊ณ ์ถ์ง๋ง ์ฌ๋ฌ ์ฟผ๋ฆฌ ๋ฉ์๋์ ๋ ๋ง์ if๋ฌธ์ด ์๊ฒจ์ผํด์ ์ผ๋จ null์ ๋ํ ์์ธ์ฒ๋ฆฌ๋ง ์งํํ๋ค.
https://kuk1938.tistory.com/208
โป ํด๋น ๊ธ ๋ง์ง๋ง์ JPQL๊ณผ ๊ฐ์ด ํ๋ ค๋ฉด ์ฟผ๋ฆฌ๋ฉ์๋๊ฐ ์ฌ๋ฌ๊ฐ ๋์์ผํ๋ค.
- TodoRepositoryCustom, TodoRepositoryImpl์์ ์ธํ ํ ์ฟผ๋ฆฌ๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ TodoSearch DTO์์ ์ต์ข ์ผ๋ก ์กฐํํด์ผํ ๊ฐ์ ๋ฐํ์์ผ์ค๋ค.
๐งช - ์ต์ข ํ ์คํธ
- ์ฟผ๋ฆฌ๊ฐ ์๋ ๋ณต์กํด์ 2๊ฐ๊ฐ ํ์ฟผ๋ฆฌ
'Spring > QueryDSL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[18] Spring - QueryDSL ์ฌ์ฉ๋ฐฉ๋ฒ (1) | 2024.11.20 |
---|