π« μ΄ κΈμ κΉμνλμ 'μλ° ORM νμ€ JPA νλ‘κ·Έλλ°'μ 곡λΆνλ©° μ 리ν κ²μμ μ립λλ€.
- J2SE νκ²½μμ JPA κ°λ°μλ μ§μ μν°ν° 맀λμ λ₯Ό μμ±νκ³ νΈλμμ μ κ΄λ¦¬
- μ€νλ§ νΉμ J2EE 컨ν μ΄λ νκ²½μμ JPAλ₯Ό μ¬μ©νκΈ° μν΄μλ 컨ν μ΄λκ° μ 곡νλ μ λ΅μ λ°λ¦
-
μ€νλ§μ κ²½μ° νΈλμμ λ²μμ μμμ± μ»¨ν μ€νΈ μ λ΅μ κΈ°λ³ΈμΌλ‘ μ¬μ©
-
νΈλμμ λ²μμ μμμ± μ»¨ν μ€νΈ β νΈλμμ λ²μμ μμμ± μ»¨ν μ€νΈμ μμ‘΄ λ²μκ° κ°μ
κ°μ νΈλμμ μμμλ νμ κ°μ μμμ± μ»¨ν μ€νΈμ μ κ·Ό- λ€μν μμΉμμ μν°ν° 맀λμ λ₯Ό μ£Όμ λ°μ μ¬μ©ν΄λ νΈλμμ μ΄ κ°μ μμλ νμ κ°μ μμμ± μ»¨ν μ€νΈ μ¬μ©
- μ¬λ¬ μ€λ λμμ λμ μμ²μ΄ μμ κ°μ μν°ν° 맀λμ λ₯Ό μ¬μ©ν΄λ νΈλμμ μ λ°λΌ μ κ·Όνλ μμμ± μ»¨ν μ€νΈκ° λ€λ¦(λ©ν° μ€λ λ μν©μμ μμ )
-
μ€νλ§μμλ
@Transactional
μ΄λ Έν μ΄μ μ μ¬μ©νμ¬ νΈλμμ μ λ²μλ₯Ό μ§μ
μ¦, μ΄λ Έν μ΄μ μ΄ λΆμ λ©μλλ₯Ό μ€ννκΈ° μ§μ μ νΈλμμ AOPκ° λμνμ¬ νΈλμμ μ μμνκ³ , λ©μλκ° μ μμ μΌλ‘ μ’ λ£λμμ λλ νΈλμμ μ 컀λ°(컀λ°νκΈ° μ μ λ¨Όμ μμμ± μ»¨ν μ€νΈλ₯Ό νλ¬μ) -
λ§μ½ μ€κ°μ μμΈ λ°μμμλ νΈλμμ μ λ‘€λ°±νκ³ μ’ λ£(μμμ± μ»¨ν μ€νΈ νλ¬μ X)
-
νΈλμμ μ΄ μ΄μμλ μλΉμ€ κ³μΈ΅κ³Ό λ ν¬μ§ν 리 κ³μΈ΅μμ μν°ν°λ μμ μν
λ°λ©΄ ν리μ ν μ΄μ κ³μΈ΅μμ μν°ν°λ μ€μμ μν
λ°λΌμ ν리μ ν μ΄μ κ³μΈ΅μμλ λ³κ²½ κ°μ§μ μ§μ° λ‘λ© X -
ν리μ ν μ΄μ κ³μΈ΅μμλ μ΄λ₯Ό μ¬μ©νκΈ° μν΄μλ μ¬λ¬κ°μ§ λ°©λ²μ΄ μ‘΄μ¬
-
κΈλ‘λ² νμΉ μ λ΅ μμ
-
μ§μ° λ‘λ© β μ¦μ λ‘λ©
-
μ΄ λ λ°μν μ μλ λ¬Έμ 2κ°μ§
-
μ¬μ©νμ§ μλ μν°ν°λ₯Ό λ‘λ©
AλΌλ λ·°μμλ Orderμ Member λ λ€ μ¬μ© BλΌλ λ·°μμλ Orderλ§ μ¬μ©
μ¦μ λ‘λ© μ λ΅μΌλ‘ μΈν΄ Bμμλ Order, Member λ λ€ λ‘λ©
-
N+1 λ¬Έμ λ°μ(JPQL μ¬μ©μ)
JPAκ° JPQLμ λΆμνμ¬ SQLμ μμ±ν λ κΈλ‘λ² νμΉ μ λ΅μ μ°Έκ³ X
λ°λΌμ Orderμ λ¨Όμ κ°μ Έμ€κ³ λμ Memberμ μ λ΅μ΄ μ¦μ λ‘λ©μ΄λ―λ‘ κ·Έμ μμΌ Memberλ₯Ό κ°μ Έμ΄
μ΄ λ, Memberμ μλ§νΌ SQLλ¬Έμ΄ λ°μνλ―λ‘ μ΄λ₯Ό N+1μ΄λΌκ³ ν¨μ΄λ JPQL νμΉ μ‘°μΈμΌλ‘ ν΄κ²° κ°λ₯
-
-
-
JPQL νμΉ μ‘°μΈ
- Join λͺ λ Ήμ΄ λ§μ§λ§μ fetchλ₯Ό λ£μ΄μ£Όλ©΄ λ¨
- N+1 λ¬Έμ λ₯Ό ν΄κ²°νλ©΄μ νλ©΄μ νμν μν°ν°λ₯Ό 미리 λ‘λ©νλ νμ€μ μΈ λ°©λ²
- 무λΆλ³νκ² μ¬μ©μ νλ©΄μ λ§μΆ λ ν¬μ§ν 리 λ©μλκ° μ¦κ°
μ¦, λ·°μ λ ν¬μ§ν 리 κ°μ λ Όλ¦¬μ μΈ μμ‘΄μ±μ΄ λ°μ
-
κ°μ μ΄κΈ°ν
-
μμμ± μ»¨ν μ€νΈκ° μ΄μμμ λ ν리μ ν μ΄μ κ³μΈ΅μ΄ νμν μν°ν°λ₯Ό κ°μ λ‘ μ΄κΈ°ν
@Transactional public Order findOrder(Long id) { Order o = orderRepository.findOrder(id); o.getMember().getName(); // νλ‘μ κ°μ²΄ κ°μ μ΄κΈ°ν return o; }
-
νμ΄λ²λ€μ΄νΈλ₯Ό μ¬μ©νλ©΄
initialize()
λ©μλλ₯Ό μ¬μ©νμ¬ νλ‘μλ₯Ό κ°μ λ‘ μ΄κΈ°ν(JPA νμ€μμ μμ) -
μλΉμ€ κ³μΈ΅μμ ν리μ ν μ΄μ κ³μΈ΅μ νμν μν°ν°λ₯Ό μ΄κΈ°ν νλ€λ©΄ μλΉμ€κ° ν리μ ν μ΄μ μ μ’ μμ μ΄κ² λλ―λ‘ μ€κ° κ³μΈ΅μ λμ΄ λΆλ¦¬, μ΄κ° λ°λ‘ FACADE κ³μΈ΅
-
-
FACADE(νΌμ¬λ) κ³μΈ΅ μΆκ°
-
-
μ΄ λͺ¨λ λ¬Έμ λ μν°ν°κ° ν리μ ν μ΄μ μμλ μ€μμ μνμ΄κΈ° λλ¬Έμ λ°μ
- OSIVλ μμμ± μ»¨ν
μ€νΈλ₯Ό ν리μ ν
μ΄μ
κ³μΈ΅κΉμ§ μ΄μ΄ λλ κ²μ λ»ν¨
λ°λΌμ λ·°μμλ μ§μ° λ‘λ©κ³Ό λ³κ²½ κ°μ§λ± μ¬μ© κ°λ₯ - OSIVλ νμ΄λ²λ€μ΄νΈμμ μ¬μ©νλ μΈμ΄λ‘ JPAμμλ OEIV(Open EntityManager In View)λΌκ³ ν¨
-
ν΄λΌμ΄μΈνΈμ μμ²μ΄ λ€μ΄μ€μλ§μ μλΈλ¦Ώ νν° νΉμ μ€νλ§ μΈν°μ ν°μμ νΈλμμ μ μμ, μμ²μ΄ λλλ©΄ νΈλμμ λ λ
μ΄λ₯Ό μμ² λΉ νΈλμμ OSIVλΌκ³ ν¨ -
μ΄μ κ°μ₯ ν° λ¬Έμ μ μ ν리μ ν μ΄μ κ³μΈ΅μμ μν°ν° λ³κ²½μ΄ κ°λ₯νλ€λ κ²
ν리μ ν μ΄μ κ³μΈ΅μμ μν°ν°λ₯Ό λ³κ²½ν λ€ μμ²μ λλ΄λ©΄ μλν κ²μ΄ μλλλΌλ λ°μ΄ν°λ² μ΄μ€μ λ°μμ΄ κ°λ₯
-
μ΄λ‘μΈν΄ μ μ§λ³΄μκ° μλΉν νλ€μ΄μ§λ―λ‘ λ€μκ³Ό κ°μ λ°©λ²μ μ¬μ©
-
μν°ν°λ₯Ό μ½κΈ° μ μ© μΈν°νμ΄μ€λ‘ μ 곡
-
μ½κΈ° μ μ© λ©μλλ§ μ 곡νλ μΈν°νμ΄μ€λ₯Ό ν리μ ν μ΄μ κ³μΈ΅μ μ 곡
interface MemberView { public String getName(); } @Entity class Member implements MemberView { ... } class MemberService { public MemberView getMember(Long id) { return memberRepository.findById(id); } }
-
-
μν°ν° λν
-
μν°ν°μ μ½κΈ° μ μ© λ©μλλ§ κ°μ§κ³ μλ μν°ν°λ₯Ό κ°μΌ κ°μ²΄λ₯Ό λ§λ€κ³ μ΄λ₯Ό λ°ν
class MemberWrapper { private Member m; public MemberWrapper(Member m) { this.m = m; } public String getName() { return m.getName(); } }
-
-
DTO λ°ν
- κ°μ₯ μ ν΅μ μΈ λ°©λ²μΌλ‘ λ¨μν λ°μ΄ν°λ§ μ λ¬νλ DTOλ₯Ό μμ±νμ¬ λ°ν
- OSIVλ₯Ό μ¬μ©νλ μ₯μ μ μ΄λ¦΄ μ μκ³ μν°ν°λ₯Ό 볡μ¬ν λ―ν DTO ν΄λμ€λ₯Ό λ§λ€μ΄μΌ νλ λ¨μ
-
-
μ΄λ¬ν λ¬Έμ μ λ€μ 보μνκΈ° μν΄ λΉμ§λμ€ κ³μΈ΅μμλ§ νΈλμμ μ μ μ§νλ λ°©μμ OSIVλ₯Ό μ¬μ©(μ€νλ§μμ μ 곡νλ OSIV)
-
spring-orm.jar μμλ λ€μν OSIV ν΄λμ€ μ 곡
-
OSIVλ₯Ό μ¬μ©νμ§λ§ νΈλμμ μ λΉμ§λμ€ κ³μΈ΅μμλ§ μ¬μ©
-
λμ μ리
- ν΄λΌμ΄μΈνΈμ μμ²μ΄ λ€μ΄μ€λ©΄ μλΈλ¦Ώ νν°λ μ€νλ§ μΈν°μ ν°μμ μμμ± μ»¨ν μ€νΈ μμ±
- μλΉμ€ κ³μΈ΅μμ
@Transactional
λ‘ μΈνμ¬ νΈλμμ μ΄ μμν λ, 미리 μμ±ν΄ λ μμμ± μ»¨ν μ€νΈλ₯Ό μ°Ύμμ μμ - μλΉμ€ κ³μΈ΅μ΄ λλλ©΄ μμμ± μ»¨ν μ€νΈ νλ¬μ λ° νΈλμμ 컀λ°, μ’ λ£
- ν리μ ν μ΄μ κ³μΈ΅κΉμ§ μμμ± μ»¨ν μ€νΈκ° μ μ§λλ―λ‘ μν°ν°λ μμ μν μ μ§
- λͺ¨λ μμ μ΄ λλκ³ μλΈλ¦Ώ νν° νΉμ μ€νλ§ μΈν°μ ν°μ μλ΅μ΄ κ°λ©΄ μμμ± μ»¨ν μ€νΈλ₯Ό μ’ λ£, νλ¬μ X
-
μν°ν°λ₯Ό λ³κ²½νμ§ μκ³ λ¨μν μ‘°νν λλ νΈλμμ μ΄ νμ X, μ΄λ₯Ό νΈλμμ μμ΄ μ½κΈ°λΌκ³ ν¨
-
λ§μ½ ν리μ ν μ΄μ κ³μΈ΅μμ μν°ν°λ₯Ό μμ νκ³ νΈλμμ μ μμνλ μλΉμ€ κ³μΈ΅μ νΈμΆνλ©΄ λ¬Έμ λ°μ
미리 λ³κ²½ νμ νΈλμμ μμΌλ‘ λ€μ΄κ° νλ¬μκ° λ μ μκΈ° λλ¬Έ
-
μ¬λ¬ νΈλμμ μ΄ νλμ μμμ± μ»¨ν μ€νΈλ₯Ό 곡μ νλ―λ‘ μ£Όμ(νΉν νΈλμμ λ‘€λ°± μ μ£Όμ)
-
κΌ OSIVλ§μ΄ λ΅μ μλ, μ¬λ¬κ°μ§ μν°ν°λ₯Ό μ¬μ©νλ λ·°μ κ²½μ° JPQLμ μμ±νμ¬ DTOλ‘ μ‘°ννλ κ²μ΄ λ ν¨κ³Όμ
-
JVMμ λ²μ΄λ νκ²½(μΈλΆ API νΈμΆ μ)μμλ OSIVλ₯Ό μ¬μ©ν μ μκΈ° λλ¬Έμ μν°ν°λ₯Ό μ§μ λ ΈμΆνλ κ²μ΄ μλ DTOλ‘ λ³κ²½ν λ€μ λ ΈμΆνλ κ²μ΄ μμ