2022. 10. 12. 16:10ใ์ธํ๋ฐ/์ค์ ! QueryDSL
1๏ธโฃ ์์ JPA ๋ฆฌํฌ์งํ ๋ฆฌ์ Querydsl
- ์์ JPA๋ฆฌํฌ์งํ ๋ฆฌ
MemberJpaRepository
์คํ๋ง ๋ฐ์ดํฐ JPA ์์ด ์์ํ JPA ๋ง์ ์ฌ์ฉํ ๋ฆฌํฌ์งํ ๋ฆฌ์ด๋ค.
์ฐธ๊ณ ๋ก findByIdํ ๋ ๋ฆฌํดํ์ ์ Optional๋ก ์คฌ๋๋ฐ ์ด์ ๋ id๋ก ์กฐํ๋ฅผ ํ์ ๋, ์ด์ ํด๋นํ๋ ํ์์ด ์์ ์๋ ์๊ธฐ ๋๋ฌธ์ Optional๋ก ํ๋ฒ ๊ฐ์ธ์ ๋ฆฌํดํด์คฌ๋ค.
- ์์ JPA๋ฆฌํฌ์งํ ๋ฆฌ ํ ์คํธ
-> ์์์ ๋ง๋ MemberJpaRepository๊ฐ ๋ฌธ์ ์์ด ์ ๋์๊ฐ๋์ง ๋จ์ํ ํ์ธํ๊ธฐ ์ํ ํ ์คํธ์ด๋ค.
(ํ ์คํธ ๊ฒฐ๊ณผ๋ ๋น์ฐํ ์ฑ๊ณต)
2๏ธโฃ Querydsl ์ฌ์ฉ
- ์์ JPA๋ฆฌํฌ์งํ ๋ฆฌ : Querydsl ์ถ๊ฐ
findAll()๊ณผ findByUsername()์ ๋ํด์ Querydsl์ง ์ฝ๋์ด๋ค.
(ํ์คํ ํจ์ฌ ๊ฐ๋ ์ฑ์ด ์ข์ ๊ฒ ๊ฐ๋ค.)
- QueryDsl์ ๋ํ ํ ์คํธ ์ถ๊ฐ
์์์ ํ๋ ํ ์คํธ์์ findAll() ์ findAll_Querydsl()๋ก, findByUsername()์ findByUsername_Querydsl()๋ก ๋ณํํด์ ํ ์คํธ๋ง ์งํํด์ฃผ๋ฉด ๋๋ค. (์ด์ฐจํผ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๊ธฐ ๋๋ฌธ)
โญ๏ธ JpaQueryFactory ์คํ๋ง ๋น ๋ฑ๋กํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์ง๊ธ JpaQueryFactory๋ฅผ ์ฌ์ฉํ ๋๋ ์์ฑํ ๋๋
์ด๋ฐ์์ผ๋ก ์์ฑ์์์ JpaQueryFactory๋ฅผ ์๋ก ์์ฑํด์ EntityManagrer๋ฅผ ์ฃผ์ ํด์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๊ณ ์๋ค.
๊ทธ๋ฐ๋ฐ ๊ทธ๋ฅ JpaQueryFactory๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
์ด๋ ๊ฒ ๋น์ผ๋ก ๋ฑ๋กํด์ฃผ๊ณ , ๊ทธ๋ฅ ์์กด์ฑ ์ฃผ์ ๋ฐ์์ ์ฌ์ฉํด๋ ๋๋ค.
์ด ๋ฐฉ๋ฒ์ผ๋ก ํ๋ฉด ๋กฌ๋ณต์ @RequiredArgsConstructor๋ฅผ ์ฌ์ฉํด์ ์์ฑ์์ ๋ํ ์ฝ๋๋ฅผ ์ค์ผ ์ ์๋ค๋ ์ฅ์ ์ ์์ง๋ง,
ํ ์คํธ ํ ๋ ์์กด์ฑ์ ๋ํด์ 2๊ฐ ์ถ๊ฐํด์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ํ ์คํธํ ๋๋ ์กฐ๊ธ ๋ ๋ฒ๊ฑฐ๋กญ๋ค๋ ๋จ์ ์ด ์๋ค.
์ด๊ฑด ๊ทธ๋ฅ ์ ํํด์ ์๊ธฐ๊ฐ ํ๊ณ ์ถ์ ๋ฐฉ์๋๋ก ํ๋ฉด ๋๋ค๊ณ ํ๋ค~~
โ๏ธ ์ฐธ๊ณ : ๋์์ฑ ๋ฌธ์ ์ ๋ํด์๋ ๊ฑฑ์ ํ์ง ์์๋ ๋๋ค.
์๋ํ๋ฉด ์ฌ๊ธฐ์ ์คํ๋ง์ด ์ฃผ์ ํด์ฃผ๋ ์ํฐํฐ ๋งค๋์ ๋ ์ค์ ๋์ ์์ ์ ์ง์ง ์ํฐํฐ ๋งค๋์ ๋ฅผ ์ฐพ์์ฃผ๋ ํ๋ก์์ฉ ๊ฐ์ง ์ํฐํฐ ๋งค๋์ ์ด๋ค. ์ด ๊ฐ์ง ์ํฐํฐ ๋งค๋์ ๋ ์ค์ ์ฌ์ฉ ์์ ์ ํธ๋์ญ์ ๋จ์๋ก ์ค์ ์ํฐํฐ ๋งค๋์ (์์์ฑ ์ปจํ ์คํธ)๋ฅผ ํ ๋นํด์ค๋ค.
3๏ธโฃ ๋์ ์ฟผ๋ฆฌ์ ์ฑ๋ฅ ์ต์ ํ ์กฐํ - Builder ์ฌ์ฉ
MemberTeamDto
: ์กฐํ ์ต์ ํ์ฉ DTO ์ถ๊ฐ
์ด๋ฒ์๋ ์์ฑ์์ @QueryProjection์ ์ฌ์ฉํด์ Qํ์ผ์ ๋ง๋ค์ด์ฃผ๊ณ DTO๋ฅผ ํ๋ก์ ์ ์ผ๋ก ์กฐํํด์ฌ ๊ฒ์ด๋ค.
์ด๋ QMEmberTeamDto๋ฅผ ์์ฑํ๊ธฐ ์ํด ./gradlew compileJava ํ๋ฒ ํด์ฃผ๊ณ , build -> rebuild Project ํด์ฃผ๊ธฐ~
โ๏ธ ์ฐธ๊ณ
@QueryProjection์ ์ฌ์ฉํ๋ฉด ํด๋น DTO๊ฐ QueryDsl์ ์์กดํ๊ฒ ๋๋ค.
์ด๋ฐ ์์กด์ด ์ซ๋ค๋ฉด ํด๋น ์ด๋ ธํ ์ด์ ์ ์ ๊ฑฐํด์ฃผ๊ณ Projection.bean(), Projection.fields(), Projections.constructor() ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
https://hyejin.tistory.com/821
MemberSearchCondition
: ํ์ ๊ฒ์ ์กฐ๊ฑด
๋์ ์ฟผ๋ฆฌ : Builder ์ฌ์ฉ
MemberJpaRepository
username๊ณผ teamname์ ๋ํด์ null ์ฒดํฌํ ๋๋ StringUtils์ hasText() ํจ์๋ฅผ ํตํด ๊ฒ์ฆํด์คฌ๋ค.
๋ฐ๋ผ์ null ์ด ์๋๋ฉด BooleanBuilder ์ and ์กฐ๊ฑด์ผ๋ก ์ถ๊ฐํด์ค๋ค.
๋์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ builder ์ ๋ํด์๋ where ์กฐ๊ฑด์ builder๋ฅผ ์ถ๊ฐํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
์กฐํ ์์ ํ ์คํธ
๊ฒ์ ์กฐ๊ฑด์ 35 ~ 40 ์ด ์ฌ์ด๋ฅผ ์กฐํํ๊ณ , ๊ทธ ๋ค์ team ์ด๋ฆ์ teamB์ธ ํ์์ ๊ฒ์ํ๋ ํ ์คํธ์ด๋ค.
๊ทธ๋ ๊ฒ ํด์ ๋์จ ํ ์คํธ ๊ฒฐ๊ณผ๋ member4๊ฐ ์ ๋์ค๋ฉด ๋๋ค.
4๏ธโฃ ๋์ ์ฟผ๋ฆฌ์ ์ฑ๋ฅ ์ต์ ํ ์กฐํ - Where์ ํ๋ผ๋ฏธํฐ ์ฌ์ฉ
MemberJpaRepository
: Where ์ ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ ์์
BooleanBuilder ์ฌ์ฉํ ๋๋ ๋น์ทํ๊ธด ํ๋ฐ ์ด๋ฒ์๋ where ์กฐ๊ฑด์ ํ๋ผ๋ฏธํฐ ๋ก ์กฐ๊ฑด์ ๋์ดํ๋ค.
usernameEq, teamNameEq, ageGoe, ageLoe ๋ฉ์๋๋ฅผ ๋ฐ๋ก ๋นผ์ ์กฐ๊ฑด์ผ๋ก ์ถ๊ฐํด์คฌ๋ค.
์ด๋ where ์ ์ Null์ ๋ฌด์๋๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ถ๊ฐํด์ค๋ ๋๋ค.
์ด ๋ฐฉ๋ฒ์ ์ฅ์ ์ ์กฐ๊ฑด ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ ์ ์ด๋ค.
-> ์ด๋ฐ์์ผ๋ก where ํ๋ผ๋ฏธํฐ ๋ฐฉ์์ ๋ค๋ฅธ query์์๋ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
5๏ธโฃ ์กฐํ API ์ปจํธ๋กค๋ฌ ๊ฐ๋ฐ
๊ฐ๋จํ API๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ๊ฒ์ด๋ค.
๊ทผ๋ฐ ์ด ์ํ ๋ฐ์ดํฐ๊ฐ ํ ์คํธ์ ์ํฅ์ ์ฃผ์ง ์๋๋ก ํ๋กํ์ผ์ ์ค์ ํด์ค๋ค.
- ํ๋กํ์ผ ์ค์
src/main/resoureces/application.yml
src/test/resources/application.yml
: ํ ์คํธ๋ ๊ธฐ์กด application.yml ์ ๋ณต์ฌํด์ ๋ค์ ๊ฒฝ๋ก๋ก ๋ณต์ฌํ๊ณ , ํ๋กํ์ผ์ test๋ก ์์
-> ์ด๋ ๊ฒ ๋ถ๋ฆฌ๋ฅผ ํด์ฃผ๋ฉด main ์์ค์ฝ๋์ ํ ์คํธ ์์ค์ฝ๋ ์คํ ์ ํ๋กํ์ผ์ ๋ถ๋ฆฌํ ์ ์๋ค.
- ์ํ ๋ฐ์ดํฐ ์ถ๊ฐ
InitMember
InitMember ํด๋์ค์์ ๋ด๋ถ์ InitMemberService๋ฅผ ๋ง๋ค์ด์ Team๊ณผ Member ๋ฅผ ๋ง๋ค์ด์ค๋ค.
๋์ค์ ํ์ด์ง ๊ด๋ จํด์๋ ํ ์คํธํด์ผํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ๋ฅผ 100๊ฐ ๋ง๋ค์ด๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ ์ ๊ตณ์ด InitMemberService ๋ผ๋ ๊ฒ์ ๋ง๋ค์๋๊ฐ? ์ ๋ํด์๋
@PostConstruct ์ด๋ ธํ ์ด์ ๊ณผ @Transactional ์ด๋ ธํ ์ด์ ์ด ํจ๊ป ๋์์ด ์ ์๋๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค.
- ์กฐํ ์ปจํธ๋กค๋ฌ
MemberController
์ฌ๊ธฐ์๋ ๊ทธ๋ฅ ๊ฐ๋จํ MemberSearchCondition๋ง ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํด์ฃผ๋ฉด ๋๋ค.
์ด ์์ ๋ฅผ ์คํํ๊ธฐ ์ํด์ ํฌ์คํธ๋งจ์ ์ด์ฉํด์ ํ ์คํธํ๋ค.
http://localhost:8080/v1/members?teamName=teamB&ageGoe=30&ageLoe=60