์คํ๋ง๊ณผ JPA๋ฅผ ์ด์ฉํ ์น๊ฐ๋ฐ_JQPL
๐คJPQL์ ํน์ง์ ์์๋ณด์ !
1. Polymorphism
- book๊ณผ blogpost๋ฅผ ํฌํจํ๋ publication ์กฐํ ๊ฐ๋ฅ(book๋ ๊ฐ๋ณ์ ์ผ๋ก ์กฐํ ๊ฐ๋ฅ)
- SELECT p FROM Publication p
- SELECT b FROM BlogPost b
2. Restriction
- where์์ ์กฐ๊ฑด ๊ฑธ๊ธฐ(๊ฒ์ ๋์ ์ ํ)
SELECT a FROM Author a WHERE a.firstName like ‘%and%’ and a.id >= 20 and size(author.books) >= 5
3. Projection
- ํ ์ด๋ธ์ ๋ชจ๋ ์ปฌ๋ผ์ด ์๋ ํน์ ๊ฐ(์ปฌ๋ผ) ๋ง ์ง์ ํด์ ์กฐํ
- Projection์ ๋ค์ํ ๋์์ ์ ์ฉ ๊ฐ๋ฅ
- Entities๋ง๋ ๋ฝ์๋ผ ์ ์์ง๋ง!
- SELECT a FROM Author a
- Scalar values
- SELECT a.firstName, a.lastName FROM Author a
- Constructor references(DTO์ ๋งคํ)
- SELECT new org.thoughts.on.java.model.AuthorValue(a.id, a.firstName, a.lastName) FROM Author a
4. Distinct query results
- ์ค๋ณต๋๋ ์ฟผ๋ฆฌ๋ฅผ ์ ์ธํ๊ณ ์กฐํ
- SELECT DISTINCT a.lastName FROM Author a
5. Function
- upper(String s)
- lower(String s)
- current_date()
- current_time()
- current_timestamp()
- โก๏ธSQL์์๋ ์ด๋ฌํ Function์ ์ฌ์ฉํ ์ ์๋๋ฐ JPQL์์๋ ๋๊ฐ์ด ์ฌ์ฉ ๊ฐ๋ฅํจ!
6. Ordering - The ORDER BY clause
- ์ ๋ ฌ ๋ฐฉ์ ์ง์ : ascending (ASC) or a descending (DESC) order
- SELECT a FROM Author a ORDER BY a.lastName ASC, a.firstName DESC
Join๋ ๊ฐ๋ฅํ๋ค!
1. Inner Joins
SELECT a, b FROM Author a JOIN a.publications b
โ ๏ธInner Joins์ด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ publication์ด ์๋๋ผ a.publication์ด์ด์ผ ํจ !!
์ฐจ์ด๋ฅผ ์ดํดํ์๊ฒ ์ฃ ?
- FROM ์ ์ select ๋์์ด ๋๋ ์ํฐํฐ๋ฅผ ์ง์ ํ๊ธฐ ์ํด ์ฌ์ฉ
- Author ์ํฐํฐ๊ฐ Hibernate์ publications ์ํฐํฐ์ ์ด๋ป๊ฒ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋์ง ์๋ ค์ฃผ๋ฏ๋ก ์ถ๊ฐ์ ์ธ ON์ ์ด ํ์ ์์
- ์ฐ๊ด๊ด๊ณ๊ฐ ์ค์ ๋์ง ์์ ์ํฐํฐ๊ฐ ์กฐ์ธ์ JPA์์ ์ ๊ณตํ์ง ์์. ๋์ ์ธํ ์กฐ์ธ์ WHERE์ ์ ์ด์ฉํ์ฌ ์กฐ์ธ์ ์ํ
SELECT b, p FROM Book b, Publisher p WHERE b.fk_publisher = p.id
2. Left Outer Joins
- ์ฐ๊ด๊ด๊ณ ์ฌ๋ถ์ ์๊ด ์์ด ๋์ ์ํฐํฐ๋ ๋ชจ๋ ์กฐํํ ๋ ์ฌ์ฉ
- ์ด์ ์์ ์ INNER์กฐ์ธ์ publication ์ด๋ ฅ์ด ์๋ Author๋ง ์กฐํ๋๋ค๋ฉด Left Outer ์กฐ์ธ์ publication ์ฌ๋ถ์ ์๊ด์์ด ๋ชจ๋ ์กฐํ
- SELECT a, b FROM Author a LEFT JOIN a.publications b
3. Additional Join Conditions
- JPA 2.1๋ถํฐ INNER ์กฐ์ธ์ ON์ ์ง์
4. Join Fetch
- ๋์ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ ์ฐ๊ด ์ํฐํฐ๋ ํจ๊ป ์กฐํ
- FetchType์ Lazy๋ก ๋๋ ๊ฒ์ ๊ถ์ฅํ์ง๋ง ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
- ์ด๋, Join Fetch์ฌ์ฉ
- ์๋๋ ํ์ ์ ์๊ณ ์์ผ๋ฏ๋ก Query์์ฑ๊ณผ ์คํ์ ์ฒด์ด๋ ํํ๋ก ์ํ
๐ถ์์ : Join Fetch์ ํ์ฉํด๋ณด์!
๊ทธ.์ .์ ๋ฐํํ์ ์ ์ง์ ํ JPQL์ ์ฌ์ฉํ๊ณ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ์คํํ๋ฉด SELECT๋ฌธ์ด 2๋ฒ ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
์ด ์ด์ ๋ Person์ด LAZY์ด๊ธฐ ๋๋ฌธ์ query.getResultList()๊ฐ ์คํ๋ ๋ 1๋ฒ, forEach๋ฌธ์ผ๋ก ์คํ๋ ๋ ์ฐ๊ด๊ด๊ณ์ธ address๊น์ง 1๋ฒ ๋ ์คํ๋๊ธฐ ๋๋ฌธ์ด๋ค.
โก๏ธ์ด๋ ์ฑ๋ฅ์ ์น๋ช ํ๋ฅผ ์ค ์ ์์ผ๋ฏ๋ก ์ต๋ํ SELECT๋ฌธ์ ์ต์ํ์ผ๋ก ์คํ์ํค๋ ๊ฒ์ด ์ข๋ค.
โ ๏ธํ์ง๋ง fetchType์ EAGER์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ์คํ๋ ค ์ฑ๋ฅ์ ๋ ์์ข๊ธฐ ๋๋ฌธ์ ์ด๋ด๋ Join Fetch๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค!
join fetch p.addresses๋ก ๊ฐ์ ธ์ค๋ฉด SELECT๋ฌธ์ด 1๋ฒ ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
๊ทธ.๋ฌ.๋.. ์ด๋ฒ์๋ ๊ฐ์ ์ค๋ณต์ด ๋ฐ์ํ๋ค.
โก๏ธ์ด๋ด ๋์๋ distinct๋ฅผ ์ฌ์ฉํ์!
distinct๋ฅผ ์ฌ์ฉ ํ ์ค๋ณต์ด ์์ด์ก๋ค.
์ ๋ฆฌํด๋ณด์
- oneToMany๋ manyToOne์ด๋ ๊ทธ๋ฅ LAZY๋ก ์ค์ ํ๋ ๊ฒ์ด ์ด์ํ๋ ๊ด์ ์์ ์ฝ๋ค.
- ๊ทธ๋ฌ๋ ํ๋ฒ์ ์ฐ๊ด๊ด๊ณ ์ํฐํฐ๋ฅผ ์กฐํํด์ผํ ๋์๋ join fetch๋ฅผ ์ฌ์ฉํด์ ํจ๊ป ์กฐํํด์ฌ ์ ์๋ค.
- ๊ทธ๋ฆฌ๊ณ oneToMany ๊ฒฝ์ฐ์๋ join๋ฅผ ์ฌ์ฉํ ๋ ์ค๋ณต์ด ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ distinct๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.