- Published on
๐คฟ ์จ ๊พน ์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ 4 : ์จ ๊พน์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ - JPA ์๋ฆฌํธ
- Authors

- Name
- Woojin Son
์จ ๊พน์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ - JPA ์๋ฆฌํธ
- ์จ ๊พน์ฐธ๊ณ ๋ฅ๋ค์ด๋ธ - JPA ์๋ฆฌํธ
- Intro
- JPA ์ Hibernate ์ ๊ด๊ณ ๋ค์ ๋ฆฌ๋ง์ธ๋ ํ๊ธฐ
- ์ํฐํฐ ๋งค๋์ (EntityManager) - JPA ์ ์ฌ์ฅ
- ์์์ฑ ์ปจํ ์คํธ (Persistence Context)
- flush - SQL ์ด ์ค์ ๋ก ๋๊ฐ๋ ์๊ฐ
- Dirty Checking - Hibernate ์ ๊ทธ๋ฆผ์
- JPQL ๊ณผ SQL ์ ๋ง๋จ
- Spring Data JPA - EntityManager ์ ์๋ํ
- ์์ฝ : JPA ๋ฅผ ์ดํดํ๊ธฐ ์ํ ํต์ฌ ์ ๋ฆฌ
- ๋ง์น๋ฉฐ
Intro
๋ค์ ๋์์์ต๋๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ JPA ์ ์๋ฆฌ๋ฅผ ํ๋ฒ ๋ฅํ๊ฒ ํ ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฌ์ค JPA ์ ์๋ฆฌ๋ฅผ ๋ฅํ๊ฒ ํ๋ค๋ ๋ง ์์ฒด๊ฐ ์กฐ๊ธ์ ์ด์ํ ์ ์์ต๋๋ค. JPA ๊ทธ ์์ฒด๋ ์ธํฐํ์ด์ค ๋ช ์ธ์ผ ๋ฟ์ด๋๊น์.
์ฌ๊ธฐ์ ๋งํ๋ ์๋ฆฌ๋ Spring Data JPA ์ ๋์ ์๋ฆฌ, ์ค๊ณ ์ฒ ํ์ ๋ํ ์ด์ผ๊ธฐ๋ผ๊ณ ์ดํดํด์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. 'Spring Data JPA ์ Hibernate ๊ตฌํ์ฒด๊ฐ ์ด๋ป๊ฒ ๋ง ๋ฌผ๋ฆฌ๋์ง?' ๋ผ๋ ์ฃผ์ ๋ก ์๊ฐ ํด ์ฃผ์๋ฉด ๋ ๊ฒ ๊ฐ์์.
Spring ์ ์ ๋ฌธํ ์์ ์์ ์ ๋ง ์ดํด๊ฐ ์ด๋ ต๊ณ ์ ์์ด ์ด๋ ค์ ๋ ๊ฒ ์ค ํ๋๊ฐ
JpaRepository์์ต๋๋ค.๊ฐ๋ฐ์๊ฐ ์ง์ ์ปจํธ๋กคํ์ง ์๋ ํ๋ ์์ํฌ์ ์์ญ์ผ๋ก CRUD ์์ ์ด ์ฒ๋ฆฌ๋๋ ๊ฒ ํธํ๊ธด ํ์ง๋ง...๋ง์ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ๋์ ์๋ฆฌ๋ฅผ ์ ์์์ผ ํ์ฃ .
Spring ์ผ๋ก ์ฑ์ ๊ฐ๋ฐํ๊ณ ์ด์ํ๋ ๋จ๊ณ์์๋ ๋์ด์ ์ ๋ฌธ์ด ์๋๊ธฐ ๋๋ฌธ์ ํนํ ์๋ฆฌ ์ดํด๋๊ฐ ์ค์ํด์ง๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ JPA ์์ ์๋ฆฌ๋ผ๊ณ ๋ค๋ฃฐ ์ ์๋ ๊ฒ๋ค์ ์ต๋ํ ๋ค๋ค๋ณด๋ ค๊ณ ํฉ๋๋ค.
โ ์ปคํผ ํ์๊ณผ ํจ๊ป ์ฆ๊ฒจ์ฃผ์ธ์. ์ด๋ฒ์๋ ๊น๊ฒ ๋ฅ๋ค์ด๋ธ ํด ๋ณด๊ฒ ์ต๋๋ค.
JPA ์ Hibernate ์ ๊ด๊ณ ๋ค์ ๋ฆฌ๋ง์ธ๋ ํ๊ธฐ
JPA (Java Persistence API) ๋ ORM (Object Relational Mapping) ์ ์ํ ์ธํฐํ์ด์ค ๋ช ์ธ๊ณ , Hibernate ๋ JPA ๋ช ์ธ๋ฅผ ๊ตฌํํ ๋ํ์ ์ธ ๊ตฌํ์ฒด (Implementation) ์ ๋๋ค.
Spring Data JPA ๋ Hibernate ๋ฅผ JPA ๋ก ๊ฐ์ผ ์ถ์ํ ๊ณ์ธต + Repository ์๋ ๊ตฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
Application
โ
Spring Data JPA (Repository Layer)
โ
JPA Interface (EntityManager, EntityTransaction ๋ฑ)
โ
Hibernate (์ค์ ๊ตฌํ์ฒด)
โ
JDBC Driver โ Database
Spring Data JPA (Spring Boot Starter) ๋ฅผ ์ ์ ํ๋ฉด ์์ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค. ๊ฐ๋ฐ์๋ Spring Data JPA ๋ฅผ ํตํด์ DB ์ปค๋ฅ์ ์ ์ ์ ํ๊ณ , ์ํฐํฐ๋ฅผ ์ ์ํ์ฃ .
ํ์ง๋ง ๋ง์ฝ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ด ์ฐ๋ํด์ผํ๋ค๋ฉด? JPA ์ EntityManager์ EntityTransaction ์ ์ ์ ํด์ผ ํฉ๋๋ค. ์กฐ๊ธ ๋ ๊น๊ฒ ํ๊ณ ๋ค์ด์ผ ํ๋ ์์ ์ด ์ค๊ฒ ๋์ฃ .
์ํฐํฐ ๋งค๋์ (EntityManager) - JPA ์ ์ฌ์ฅ
์ํฐํฐ ๋งค๋์ (EntityManager) ๋ JPA ์ ํต์ฌ ์ธํฐํ์ด์ค์
๋๋ค. ๋ชจ๋ DB ์กฐ์์ด ์ฌ๊ธฐ์๋ถํฐ ์์ ๋์ฃ .
Spring Boot ์์๋ @PersistenceContext ๋๋ EntityManagerFactory ๋ฅผ ํตํด ์ฃผ์
๋ฉ๋๋ค.
@Service
class MemberService(
private val em: EntityManager
) {
fun save(member: Member) {
em.persist(member)
}
}
์๋ง JpaRepository ๋ฅผ ๋ถ๋ฌ์์ CRUD ๋ฅผ ํ๋ ๊ฒ ๋๋ถ๋ถ ์ต์ํ์ค๊ฒ๋๋ค. ์๋ฆฌ๋ฅผ ์๋ ๊ฒ ๋ชฉ์ ์ด๋ ์ด๋ฒ์ ์ง์ EntityManager ๋ฅผ ๋ถ๋ฌ ์ ๋ณด๊ฒ ์ต๋๋ค.
persist ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฐ ์์ด์ ๋ค ๊ฐ์ง ๋ฉ์ปค๋์ฆ์ด ๋์ํ๊ฒ ๋ฉ๋๋ค.
- ์ํฐํฐ๋ฅผ ์์์ฑ ์ปจํ ์คํธ์ ๋ฑ๋ก (1์ฐจ ์บ์ ์ ์ฅ)
- ์ค๋ ์ท ์์ฑ (๋ณ๊ฒฝ ๊ฐ์ง๋ฅผ ์ํ ์๋ณธ ๋ณต์ฌ๋ณธ ์ ์ฅ)
- ํธ๋์ญ์ ์ปค๋ฐ ์์ ์ flush() ์คํ
- JDBC batch insert ์คํ ํ DB ๋ฐ์
JPA ๋ ์ฆ์ ๋ฐ์ดํฐ๋ฅผ DB ์ ๋ฐ์ํ์ง ์์ต๋๋ค. JDBC ๋ก call ์ ํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ๋ ๊ณผ์ ์ ๊ฑฐ์น์ฃ . ์ด๋ฅผ ์ฐ๊ธฐ ์ง์ฐ (Write-behind) ์ ๋ต์ด๋ผ๊ณ ํฉ๋๋ค.
์ ์ด๋ฐ ์ ๋ต์ ์ฐ๊ฒ ๋์์๊น์? ์ฐ๋ฆฌ๊ฐ ํ์ ํ ๋ ๋ง๋ค JDBC ์ CRUD ๋ฅผ ๋ชจ๋ ํ์ฐ๊ฒ ๋๋ค๋ฉด ํ๋์ ๋น์ฆ๋์ค ๋ก์ง์์ ์ฐ์์ ์ผ๋ก DB ์๋ฒ์ Query ๊ฐ ์์ฒญ ๋ฉ๋๋ค. ์ด๋ DB ์๋ฒ์ ๋ถํ๋ฅผ ์ผ์ผํฌ ์ ์์ฃ .
์์์ฑ ์ปจํ ์คํธ (Persistence Context)
์์์ฑ ์ปจํ ์คํธ๋ ์ํฐํฐ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์์ 1์ฐจ ์บ์์ ๋๋ค.
์ํฐํฐ์ ์ํ๋ ์๋์ 4๊ฐ์ง ๋จ๊ณ๋ฅผ ๊ฑฐ์นฉ๋๋ค.
| ์ํ | ์ค๋ช |
|---|---|
| ๋น์์ (Transient) | new๋ก ์์ฑํ์ง๋ง ์์ง ์์์ฑ ์ปจํ ์คํธ์ ๋ฑ๋ก๋์ง ์์ |
| ์์ (Persistent) | em.persist()๋ฅผ ํตํด ๋ฑ๋ก๋จ (1์ฐจ ์บ์์ ์ ์ฅ) |
| ์ค์์ (Detached) | em.detach(), em.clear(), em.close()๋ก ๋ถ๋ฆฌ๋จ |
| ์ญ์ (Removed) | em.remove() ํธ์ถ ์ ์ญ์ ์์ฝ ์ํ |
๋ง์ฝ์ ํ๋์ ์ ํด์ง ํธ๋์ญ์ ๋ด์์ ์กฐํ๋ฅผ ์ฌ๋ฌ๋ฒ ์งํํ๋ ์ํฉ์ด ์๊ธด๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
๋ง์ฝ 1์ฐจ ์บ์๊ฐ ์๋ค๋ฉด ์ฐ๋ฆฌ๋ DB ์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ฌ๋ฌ๋ฒ ๋ณด๋ด์ผํ๋ ์ํฉ์ ๋์ ๋๋ค.
์์ ๋ง์๋๋ ธ๋ค์ํผ JPA ๋ ์ฐ๊ธฐ ์ง์ฐ ์ ๋ต์ ์ฑํํ๊ณ ์์ต๋๋ค. ๊ฐ๋ฅํ๋ฉด ํ๋์ ํธ๋์ญ์ ์ด ํ์คํ ๋๋ ์์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ ํ๋ ๊ฒ ์ข๊ฒ ์ฃ .
๊ทธ๋ ๋ค๋ฉด ๊ฐ์ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ 1์ฐจ ์บ์์ ๋๋ ๊ฒ ์ฌ๋ฌ๋ชจ๋ก ์ ๋ฆฌํฉ๋๋ค. ๋ฐ์ดํฐ์ ๋ณ๊ฒฝ์ด ๊ฐ์ง๋๋ฉด ๋ํฐ ์ฒดํน (Dirty Checking) ๊ธฐ๋ฅ์ด ๋์ํ๊ฒ ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ flush() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ update SQL ์ด ๋ฐ์ํ๊ฒ ๋์ฃ .
val member = em.find(Member::class.java, 1L)
member.name = "Woojin"
tx.commit() // flush() -> dirty checking -> update SQL ๋ฐ์
๋ํฐ ์ฒดํน (Dirty Checking) ์ ๋ํด์๋ ์ถํ ์ข ๋ ์์ธํ ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
flush - SQL ์ด ์ค์ ๋ก ๋๊ฐ๋ ์๊ฐ
flush ๋ ์์์ฑ ์ปจํ
์คํธ์ ๋ณ๊ฒฝ ๋ด์ฉ์ DB ์ ์ง์ ๋ฐ์ํ๋ ๊ณผ์ ์
๋๋ค.
flush ๊ฐ ํธ์ถ๋๋ ํธ๋ฆฌ๊ฑฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ํ๋ฌ์ ํธ๋ฆฌ๊ฑฐ | ์ค๋ช |
|---|---|
| ์๋ flush() ํธ์ถ ์ | ๋ช ์์ ์ผ๋ก ์์์ฑ ์ปจํ ์คํธ ๋ฐ์ |
| JPQL ์คํ ์ | JPQL์ DB ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ฏ๋ก flush ๋จผ์ ์คํ |
| ํธ๋์ญ์ ์ปค๋ฐ ์ | Spring์ด ๋ด๋ถ์ ์ผ๋ก flush ํ commit ์ํ |
commit ๊ณผ flush ๋ ๋ค๋ฆ ๋๋ค. flush ๋ DB ๋ฐ์ ์์ฝ, commit ์ ํธ๋์ญ์ ์๋ฃ๋ผ๊ณ ์ดํดํ์๋ฉด ๋๊ฒ ์ต๋๋ค.
Dirty Checking - Hibernate ์ ๊ทธ๋ฆผ์
Hibernate ์ ์ํฐํฐ๋ฅผ persist() ํ ๋ ์ค๋
์ท (์ด๊ธฐ์ํ) ๋ฅผ ํจ๊ป ์ ์ฅํฉ๋๋ค.
์ด ํ ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๋ ์์ ์์ ์ค๋ ์ท๊ณผ ํ์ฌ ๊ฐ์ฒด๋ฅผ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ์ ์ ์ฐพ์ฃ .
val member = em.find(Member::class.java, 1L)
member.name = "DevCow" // update SQL? โ ์์ง ์๋
tx.commit() // flush() ์คํ ์ update SQL ์์ฑ โ
์ํฐํฐ ๊ฐ์ฒด์ ํ๋ ๊ฐ์ด ๋ณ๊ฒฝ ๋ ๊ฒฝ์ฐ ์ฐ๋ฆฌ๋ JPA ๊ฐ ์์์ Update ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฐ๋ค๊ณ ์ดํดํ๊ณ ์์ต๋๋ค.
์ฌ์ค์ JPA ๋ update ๋ฉ์๋๊ฐ ๋ฐ๋ก ์กด์ฌํ์ง ์์ต๋๋ค. ๋ ์๊ฐ๋ ์ฟผ๋ฆฌ์์๋ UPDATE ๋ก ๋ ์๊ฐ ์ง๋ ๋ชจ๋ฅด์ง๋ง์...
JPQL ๊ณผ SQL ์ ๋ง๋จ
์๋ง JPA ๋ฅผ ํตํด ๋์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค๋ณด๋ฉด ํ๋ฒ ์ฏค์ ๋ง๋ฌ์ ์ง๋ ๋ชจ๋ฅด๋ ๊ธฐ๋ฅ์ด ๋ํ๋ฌ์ต๋๋ค. ๋ฐ๋ก JPQL ์
๋๋ค.
JPQL (Java Persistence Query Language) ๋ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ํ ์ฟผ๋ฆฌ์ ๋๋ค. Hibernate ๊ฐ ์ด๋ฅผ SQL ๋ก ๋ฐํํด์ JDBC ๋ก ์คํํ์ฃ .
val members = em.createQuery(
"select m from Member m where m.name = :name", Member::class.java
)
.setParameter("name", "Woojin")
.resultList
select member_id, name
from member
where name = ?
์ด๋ก์จ ๊ตฌ์กฐ๊ฐ ์์ฑ ๋์์ต๋๋ค.
JPA - Hibernate - JDBC ๊ฐ์ ์ฐ๊ฒฐ๊ด๊ณ์์ Spring Data JPA ๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์์ญ์ ๋น์ฆ๋์ค ๋ก์ง ์์ฑ, Hibernate ๋ฅผ ํตํ ์ํฐํฐ ๋ฐ ํธ๋์ญ์ ๊ด๋ฆฌ, ์ต์ข JDBC ๋ฅผ ํตํ ์ฟผ๋ฆฌ ์ ๋ฌ ๊ตฌ์กฐ๋ฅผ ํ๋ฒ ์ดํด๋ณด์์ต๋๋ค.
Tip! N+1 ๋ฌธ์
JPA ๋ฅผ ์ฐ๋ค๋ณด๋ฉด ํ๋ฒ ์ฏค์ ํ๊ฒ ๋๋ ์ค์์ฃ . N+1 ๋ฌธ์ ์
๋๋ค.
JPA ์ํฐํฐ๋ก ์ฐ๋ฆฌ๊ฐ ์ฐ๊ด๊ด๊ณ ๋งคํ์ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ฃ . ์ธ๋ํค๋ฅผ ํตํด JOIN ํด ์ฌ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๊ฐ์ ธ์ฌ ์ ์์ง๋ง...์์นซ ์๋ชป ์ฌ์ฉํ๋ค๊ฐ N+1 ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ N + 1 ๋ฌธ์ ๋ฅผ ํ๋ฒ ์ค๋ช ํ๊ณ ๋์ด๊ฐ์๋ฉด, ์ฐ๊ด๊ด๊ณ ๋งคํ์ด ๋์ด์๋ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋ 1๋ฒ์ ์ด๊ธฐ ์ฟผ๋ฆฌ ์ธ์ ์ฐ๊ด๋ ๋ฐ์ดํฐ ๊ฐฏ์ (N) ๋งํผ ์ถ๊ฐ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
val teams = em.createQuery("select t from Team t", Team::class.java).resultList
teams.forEach { println(it.members.size) } // N+1 ๋ฐ์
์๋ฅผ ๋ค์ด ํ์ ์์๋ ๋ฉค๋ฒ๋ฅผ ์กฐํํ๊ณ ์ ํ ๋, select t form Team t ์ธ์ select m from Member m ์ N ๋ฒ ํ๊ฒ ๋๋ ์์ด์ฃ .
์ฌ์ค ์ผ๋ฐ์ ์ผ๋ก SQL ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํด์ค๋ ์ํฉ์์๋ ๋ณดํต JOIN ์ฟผ๋ฆฌ ํ๋๋ก ํด๊ฒฐ์ด ๋์ด์ผ ํ๋ ์ํฉ์ด์ฃ .
์ด ๋ฌธ์ ๋ fetchJoin ์ ์ฌ์ฉํ๋ฉด ํด๊ฒฐํ ์ ์์ต๋๋ค.
select t from Team t join fetch t.members
BatchSize ์ต์
์ ํตํด ์ด ๋ฌธ์ ๋ฅผ ํํผํ ์๋ ์์ง๋ง...๊ฐ์ธ์ ์ผ๋ก fetchJoin ๋ง ์ ์จ๋ ์ค๋ฌด์์ N+1 ์ ํํผํ ์ ์์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์๋๋ฉด ๊ทธ๋ฅ ์ฐ๊ด๊ด๊ณ ๋งคํ์ ์ฐ์ง ์๊ณ ๋ชจ๋ ์ฟผ๋ฆฌ๋ฅผ QueryDSL ๋ก ์์ฑํ๋ ๊ฒ๋ ๋ฐฉ๋ฒ์ด๊ธด ํฉ๋๋ค...
Spring Data JPA - EntityManager ์ ์๋ํ
Spring Data JPA ๋ ๋ด๋ถ์ ์ผ๋ก ๋ค์์ ์ํํฉ๋๋ค.
interface MemberRepository : JpaRepository<Member, Long>
์์ ์์์์๋ EntityManager ๋ฅผ ์ง์ ๊ฐ์ ธ์์ฃ . ํ์ง๋ง Spring Data JPA ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ตณ์ด ๊ทธ๋ด ํ์๊ฐ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ์ํ ์ํฐํฐ์ ๋ํ Repository interface ๋ง ์ ์ธ ํด ์ฃผ๋ฉด ๋์ฃ .
Spring Data JPA ๋ ๋ด๋ถ์ ์ผ๋ก ์ด๋ฐ ์ํฐํฐ Repository ์ ๋ํด SimpleJpaRepository๋ก ํ๋ก์๋ฅผ ๊ตฌํํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ด๋ถ์ ์ผ๋ก EntityManager๋ฅผ ์ฃผ์ ๋ฐ์ ๋ชจ๋ CRUD ์ฒ๋ฆฌํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ด ํ๋ก์๋ฅผ ํตํด ์ฐ๋ฆฌ๋ findByXXX ์ ๊ฐ์ ์ฟผ๋ฆฌ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ๋ ์ฐ๋ Specification ๊ธฐ๋ฅ๋ ์ฌ์ฉํ ์ ์์ฃ .
๊ฐ์ธ์ ์ผ๋ก ...Specification ๋ณด๋ค๋ QueryDSL ์ ์ข ๋ ์ ํธํ๊ธฐ๋ ํฉ๋๋ค. ๋ค๋ง QueryDSL ์ ๊ทธ ๋งํผ QClass ์์ฑ์ผ๋ก ์ธํด ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ฌด๊ฑฐ์์ง ์๋ ์์ต๋๋ค.
์ฆ, ์ฐ๋ฆฌ๊ฐ ์ง์ EntityManager๋ฅผ ๋ค๋ฃจ์ง ์์๋ Spring์ด ํธ๋์ญ์ ๊ฒฝ๊ณ ๋ด์์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์๋ ๊ด๋ฆฌํด์ค ์ ์์ต๋๋ค.
์์ฝ : JPA ๋ฅผ ์ดํดํ๊ธฐ ์ํ ํต์ฌ ์ ๋ฆฌ
์ง๊ธ๊น์ง Spring Data JPA - Hibernate - JDBC ๊ฐ์ ์ฐ๊ด์ฑ, ๊ทธ๋ฆฌ๊ณ ์ํฐํฐ ํด๋์ค๋ฅผ ์กฐํ ํด ์ค๋ ๊ณผ์ ์ ํตํด JPA ์ ๋์ ์๋ฆฌ๋ฅผ ์ดํด ๋ณด์์ต๋๋ค.
์ง๊ธ๊น์ง์ ๋ด์ฉ์ ๋ค์ฏ์ค๋ก ์์ฝ ํด ๋ณด๊ฒ ์ต๋๋ค.
- JPA๋ ORM ํ์ค ์ธํฐํ์ด์ค, Hibernate๋ ๊ทธ ๊ตฌํ์ฒด ์ ๋๋ค.
- EntityManager๊ฐ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
- flush๋ ์ปค๋ฐ ์ ์ ๋ณ๊ฒฝ ๋ด์ฉ์ DB์ ๋ฐ์ํ๋ ์์ฝ ๋ช ๋ น ์ ๋๋ค.
- ๋ํฐ ์ฒดํน์ ์ค๋ ์ท ๊ธฐ๋ฐ ๊ฐ์ฒด ๋ณ๊ฒฝ ํ์ง ๋ฉ์ปค๋์ฆ ์ ๋๋ค.
- JPQL์ ์ํฐํฐ๋ฅผ ๋์์ผ๋ก ํ๋ SQL ์ถ์ํ ์ธ์ด ์ ๋๋ค.
๋ง์น๋ฉฐ
์ด๋ฒ ํฌ์คํ ์์๋ JPA ์ ์๋ ์๋ฆฌ์ ๋ํด ์์๋ณด์์ต๋๋ค.
JPA ๋ ๋จ์ํ DB ์ ์ฟผ๋ฆฌ๋ฅผ ๋์ ๋ ๋ ค์ฃผ๋ ๋๊ตฌ๋ผ๊ณ ๋ณด๊ธด ์ด๋ ต์ต๋๋ค.
DB ์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ๊ธฐ ์ , ๋ด๋ถ ๋ก์ง์ ํตํด ์ต์ข ์ ๋ฌํ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํ ํด์ฃผ๋ ๋๊ตฌ์ฃ . ํ๋์ ํธ๋์ญ์ ์์ ๋ถํ์ํ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ง์์ฃผ๊ธฐ๋ ํ์ฃ .
JDBC ๋ง ๊ฐ์ง๊ณ ๊ฐ๋ฐํ ๋์ ๋นํด ๊ฐ๋ฐ์๋ค์ด ์ ๋ฌํ๋ ์ฟผ๋ฆฌ๋ค์ ์ด๋์ ๋๋ ์ต์ ํ์์ผ์ฃผ๊ธฐ๋ ํ์ง๋ง SQL ์ฟผ๋ฆฌ ์์ฒด๋ฅผ ํ๋์์ผ์ฃผ๋ ๊ฒ์ ์๋๋๋ค. ๋ถํ์ํ๊ฒ ์ฌ๋ฌ๋ฒ ํธ์ถํ์ง ์๋๋ก ๋์์ฃผ๋ ์ญํ ์ ํ์ฃ .
๋ค๋ง, ์ด๋ฐ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ์ค๋ฌด๋ฅผ ํ๋ค๋ณด๋ฉด ๋จ์ ์ํฐํฐ SELECT ๋ฅผ ํ๋ค๊ณ ์๊ฐํ์ง๋ง, DBA ์ ์ฅ์์๋ ์ด๋ฐ ์ด์ผ๊ธฐ๋ฅผ ํ ์๋ ์์ด์.
์๋ ์ ์๊พธ SELECT * ๋ฅผ ๋๋ฆฌ๋๊ฑฐ์ผ! JPA ๋ ์ด๋์ ์๋ผ!
๊ผญ ํ์ํ ์ปฌ๋ผ๋ค๋ง ์กฐํํ๋๊ฒ ์ฌ์ค์ ๋ง๊ธฐ๋ ํฉ๋๋ค. ๋ฌผ๋ก ํ ์ด๋ธ์ ๋ฏธ๋๋ฉํ๊ฒ ์ ์ค๊ณํด๋๋ค๋ฉด ๊ด์ฐฎ๊ฒ ์ง๋ง, ๋งค๋ฒ ๊ทธ๋ ์ง๋ ๋ชปํ ์ ์๋ค๋ ๊ฒ์ ๊ฐ์ํ๊ณ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ ์ ๊ท ์๋น์ค๋ง ๊ฐ๋ฐํ๋ ๊ฑด ์๋๋๊น์.
ํนํ ์ค๋๋ ์๋น์ค๋ฅผ ๊ฑด๋ค๊ฒ ๋๋ค๋ฉด, ๊ฐ๋์ ์์ผ๋ก ๋ฑ๋ฑํ๋ฐ ๋ฐ์ดํฐ ์๊น์ง ๋ง์ ํ ์ด๋ธ์ ๊ฑด๋๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ์๊น๋๋ค. ์ด ๊ฒฝ์ฐ์๋ ์ ๋ JPA ๋ฅผ ๋ง๋ฅ์ผ๋ก ์๊ฐํด์๋ ์๋ฉ๋๋ค.
๋ค์ ํฌ์คํ ์ JPA ์ฌ์ฉ ํ์ ๋๋ค. ์ด๋ป๊ฒ ํ๋ฉด ์ค๋ฌด์์ ๋ ์ ์ธ ์ ์์ ์ง ๋ด์ฉ๋ค์ ์ ๋ฆฌํด์ ์์ฑ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!