π§ μν°ν° 맀λμ ν©ν 리 & μν°ν° 맀λμ
μμμ± μ»¨ν μ€νΈμ λν΄ μμ보기 μ μ μν°ν° 맀λμ ν©ν 리μ μν°ν° 맀λμ μ λν΄μ μμλ³΄κ² μ΅λλ€.
μν°ν° 맀λμ ν©ν 리λ μμ±λλ μμ μ DB 컀λ₯μ νμ μμ±ν΄ λ ν, κ³ κ°μ μμ²μ΄ λ€μ΄μ¬ λλ§λ€ μν°ν° 맀λμ λ₯Ό μμ±ν©λλ€.
μν°ν° 맀λμ λ DB μ°κ²°μ΄ νμν μμ (λ³΄ν΅ νΈλμμ μ΄ μμλλ κ²½μ°)μ 컀λ₯μ νμ μλ connectionμ μ»μ΅λλ€.
π§ μν°ν° 맀λμ ν©ν λ¦¬κ° μν°ν° 맀λμ λ₯Ό μ¬μ©νλ μ΄μ
μν°ν° 맀λμ ν©ν 리λ μμ±λλ μμ μ DB 컀λ₯μ νμ μμ±νκΈ°μ μμ± λΉμ©μ΄ λ§€μ° ν½λλ€.
κ·Έλ¬λ μν°ν° 맀λμ μ μμ± λΉμ©μ κ±°μ λ€μ§ μμΌλ―λ‘, μν°ν° 맀λμ ν©ν 리λ νμμ λ°λΌ μ€ν°ν° 맀λμ λ₯Ό μμ±νμ¬ μ¬μ©ν©λλ€.
μν°ν° 맀λμ ν©ν 리λ μ€λ λ μΈμ΄ν(Thread Safe)ν©λλ€.
μ¦ μ¬λ¬ μ€λ λκ° λμμ μ κ·Όνμ¬λ μμ ν λ°λ©΄, μν°ν° 맀λμ λ μ¬λ¬ μ€λ λκ° λμμ μ κ·Όν κ²½μ° λμμ± λ¬Έμ κ° λ°μνκ² λ©λλ€.
μ¦ μν°ν° 맀λμ λ μ λλ‘ κ³΅μ ν΄μλ μλ©λλ€.
π§ μμμ± μ»¨ν μ€νΈ(Persistence Context)
μν°ν°(Entity)λ₯Ό μ μ₯νκ³ κ΄λ¦¬νλ μ μ₯μμ κ°λ μ λλ€.
μμμ± μ»¨ν μ€νΈλ μν°ν° 맀λμ λ₯Ό ν΅ν΄μ μ κ·Όν μ μμ΅λλ€.
μμμ± μ»¨ν μ€νΈμ κ΄λ¦¬λλ μν°ν°μ μνλ₯Ό μμ μνλΌ ν©λλ€.
π§ μμμ± μ»¨ν μ€νΈμ νΉμ§
μλ³μ κ°
μμμ± μ»¨ν μ€νΈλ μν°ν°λ₯Ό μλ³μ κ°(@Id λ₯Ό μ¬μ©νμ¬ ν μ΄λΈμ κΈ°λ³Έ ν€(PK)μ 맀νν κ°)μΌλ‘ ꡬλΆν©λλ€.
λ°λΌμ μμ μνκ° λκΈ° μν΄μλ λ°λμ μλ³μκ° μ‘΄μ¬ν΄μΌ ν©λλ€.
π§ μμμ± μ»¨ν μ€νΈκ° μ 곡ν΄μ£Όλ κΈ°λ₯
π 1μ°¨ μΊμ
μμμ± μ»¨ν μ€νΈλ λ΄λΆμ 1μ°¨ μΊμλ₯Ό κ°μ§κ³ μμ΅λλ€.
μμ κ·Έλ¦Όμ 보면 μμμ± μ»¨ν μ€νΈμ 1μ°¨ μΊμ μμ Member κ°μ²΄κ° 1κ° λ€μ΄κ° μμ΅λλ€.
μ½λλ‘ νννλ©΄ λ€μκ³Ό κ°μ΅λλ€.
//μν°ν°λ₯Ό μμ±ν μν (λΉμμ)
Member member = new Member();
member.setId("member1");
member.serUsername("νμ1");
//μν°ν°λ₯Ό μμν, emμ EntityManager
em.persist(member);
(λΉμμμ λ§ κ·Έλλ‘ μμνλμ§ μμ μνλ₯Ό μλ―Έν©λλ€)
μ μ½λλ₯Ό μ€ννλ©΄ em.persist(member); λ₯Ό ν΅ν΄ memberκ° μμμ± μ»¨ν μ€νΈ(1μ°¨ μΊμ)μ μ μ₯λ©λλ€.
(μμμ± μ»¨ν μ€νΈλ₯Ό 1μ°¨ μΊμλΌ μ΄ν΄ν΄λ 무방ν©λλ€)
μ΄μ μ‘°νλ₯Ό νλ² ν΄λ³΄κ² μ΅λλ€.
Member member = new Member();
member.setId("member1");
member.serUsername("νμ1");
//1μ°¨ μΊμμ μ μ₯λ¨
em.persist(member);
//1μ°¨ μΊμμμ μ‘°ν
Member findMember = em.find(Member.class, "member1");
em.persist(member)λ₯Ό ν΅ν΄ memberλ₯Ό 1μ°¨ μΊμμ μ μ₯ν΄ μ€ ν, κ·Έ μνμμ μ‘°νλ₯Ό νλ μ½λμ λλ€.
μ‘°νλ₯Ό νκΈ° μν΄μλ DBμ μ°κ²°ν΄μ, DBμ μ‘΄μ¬νλ Member ν μ΄λΈμ κ°λ€ μ€ PKκ° member1 μΈ κ°μ μ°Ύμμ€λ SQLμ μνν΄μΌ ν©λλ€.
κ·Έλ¬λ 1μ°¨ μΊμ λλΆμ DBμ SQLμ μννμ§ μμλ memberμ κ°μ κ°μ Έμ¬ μ μμ΅λλ€.
μ‘°ν μ νλ¦
- "member1"μ‘°ν μμ² μ JPAλ μμμ± μ»¨ν μ€νΈμ 1μ°¨ μΊμμμ ν΄λΉ PKκ°μ κ°μ§ Memberκ°μ²΄λ₯Ό μ°Ύμ΅λλ€.
- 1μ°¨ μΊμμ μ‘΄μ¬νλ€λ©΄ κ·Έ κ°μ λ°ννκ³ , μ‘΄μ¬νμ§ μλλ€λ©΄ DBλ₯Ό μ‘°ννμ¬ κ°μ κ°μ Έμ΅λλ€.
- DBλ₯Ό μ‘°ννμ¬ κ°μ κ°μ Έμ¨ κ²½μ°λΌλ©΄, κ°μ Έμ¨ κ°μ 1μ°¨ μΊμμ μ μ₯ν΄λ‘λλ€.
- λ€μλ²μ "member1"μ μ‘°ννλ©΄, DBλ₯Ό κ±°μΉμ§ μκ³ 1μ°¨ μΊμμμ κ°μ Έμ¬ μ μκ²λ©λλ€.
κ·Έλ¦ΌμΌλ‘ ννν΄λ³΄κ² μ΅λλ€.
(μ°Έκ³ )
μν°ν° 맀λμ λ λ³΄ν΅ λ°μ΄ν°λ² μ΄μ€ νΈλμμ λ¨μλ‘ μμ±νκ³ , νΈλμμ μ΄ λλλ μμ μ μ’ λ£μν΅λλ€.
μν°ν° 맀λμ κ° μ’ λ£λλ©΄ μν°ν° 맀λμ μ 1μ°¨ μΊμμ μ‘΄μ¬νλ λ°μ΄ν°λ€λ λͺ¨λ μ§μμ§λλ€.
νΈλμμ μ κΈΈκ² λ°μνμ§ μκ³ , κ΅μ₯ν 짧μ μ°°λμ μκ°μλ§ μ‘΄μ¬ν©λλ€.
λ°λΌμ 1μ°¨μΊμλ₯Ό ν΅ν΄μ κ·Έλ κ² ν° μ±λ₯ μ΄μ μ μ»κΈ°λ νλλλ€.
π μμ μν°ν°μ λμΌμ± 보μ₯
λμΌμ± λΉκ΅: ==
λλ±μ± λΉκ΅: equals
λ€μ μ½λλ₯Ό 보며 μ€λͺ νκ² μ΅λλ€.
//Idκ° 1μΈ Member μν°ν° μ‘°ν
Member findMember1 = em.find(Member.class, 1L);
Member findMember2 = em.find(Member.class, 1L);
System.out.println(findMember1 == findMember2);//trueκ° λ°ν
JPAλ νλμ νΈλμμ μμ μ‘΄μ¬νλ(= 1μ°¨ μΊμ λ΄μ μ‘΄μ¬νλ) Id(μλ³μ κ°)κ° κ°μ μν°ν°μ λν΄μ λμΌμ±μ 보μ₯ν΄μ€λλ€.
μ¦ λ€μκ³Ό κ°μ΄ νν κ°λ₯ν©λλ€.
1μ°¨ μΊμλ‘ λ°λ³΅ κ°λ₯ν μ½κΈ°(REPEATABLE READ) λ±κΈμ νΈλμμ 격리 μμ€μ λ°μ΄ν°λ² μ΄μ€κ° μλ μ ν리μΌμ΄μ μ°¨μμμ μ 곡νλ€.
π μμ μν°ν°μ, λΉμμ νΉμ μ€μμ μν°ν°μ λΉκ΅
λμΌμ±μ 보μ₯νμ§ μμ΅λλ€.
μ½λλ₯Ό ν΅ν΄ μ΄ν΄λ³΄κ² μ΅λλ€.
Member memberA = em.find(Member.class, 1L);
em.clear();//ν΄λΉ μ½λκ° μμΌλ©΄ false, μμΌλ©΄ true
Member memberB = em.find(Member.class, 1L);
System.out.println(memberA == memberB);
μ μ½λμμ em.clear()λ‘ μμμ± μ»¨ν μ€νΈλ₯Ό λΉμμ£Όλ©΄, falseκ° μΆλ ₯λ©λλ€.
κ·Έλ λ€λ©΄ λ€μμ μ΄λ¨κΉμ?
Member memberA = em.find(Member.class, 1L);
Member memberB = em.find(Member.class, 1L);
em.clear();
System.out.println(memberA == memberB);
μ μ½λλ₯Ό μ€ν κ²°κ³Όλ trueμ λλ€.
μ΄μ λ λ€μκ³Ό κ°μ΅λλ€.
첫 λ²μ§Έ findλ₯Ό ν΅ν΄ DBμμ Memberλ₯Ό μ‘°νν©λλ€. κ·Έλ¦¬κ³ μ‘°νν λ©€λ²λ₯Ό 1μ°¨μΊμμ λ±λ‘ν©λλ€.
λ λ²μ§Έ findλ 1μ°¨ μΊμμμ κ°μ νμΈνλλ° μ‘΄μ¬ν©λλ€. λ°λΌμ 1μ°¨ μΊμμ μ‘΄μ¬νλ κ°μ κ°μ Έμ΅λλ€.
κ·Έ μ΄ν μμμ± μ»¨ν μ€νΈλ₯Ό λΉμ°λλΌλ, μ΄λ―Έ memberBλ 1μ°¨ μΊμμ μ‘΄μ¬νλ memberμ μ°Έμ‘°μ£Όμλ₯Ό κ°μ§κ³ μκΈ°μ trueκ° μΆλ ₯λλ κ²μ λλ€.
π μν°ν° λ±λ‘ μ μ°κΈ° μ§μ°
μ½λλ₯Ό ν΅ν΄ μ€λͺ νκ² μ΅λλ€.
EntityTransaction transaction = em.getTransaction();
//μν°ν° λ³κ²½μ νμ νΈλμμ
μμμ μ΄λ£¨μ΄μ ΈμΌ νλ€.
transaction.begin():
em.persist(memberA);
em.persist(memberB);
//μ¬κΈ°κΉμ§ INSERT SQLμ λ°μ΄ν°λ² μ΄μ€μ μ μ‘νμ§ μλλ€.
//νΈλμμ
μ 컀λ°νλ μκ° λ°μ΄ν°λ² μ΄μ€μ INSERT SQLμ 보λΈλ€
transaction.commit();
μμμ± μ»¨ν μ€νΈμλ 1μ°¨μΊμ λ§κ³ λ "μ°κΈ° μ§μ° μ μ₯μ"κ° μ‘΄μ¬ν©λλ€.
μ μ½λμμ em.persist(memberA);λ₯Ό νλ©΄ INSERT SQLμ΄ μμ±λμ΄ "μ°κΈ° μ§μ° μ μ₯μ"μ μ μ₯λ©λλ€.
λ§μ°¬κ°μ§λ‘ em.persist(memberB);λ₯Ό νλ©΄ INSERT SQLμ΄ μμ±λμ΄ "μ°κΈ° μ§μ° μ μ₯μ"μ μ μ₯λ©λλ€.
μ΄λ κ² κ³μ λ³κ²½μ΄ μΌμ΄λλ©΄ SQLμ μμ±νμ¬ μ°κΈ° μ§μ° μ μ₯μμ μ μ₯νλ€κ°, νΈλμμ μ΄ μ»€λ°λλ μκ° νλ²μ DBμ μ μ‘ν©λλ€.
μ΅μ
spring.jpa.properties.hibernate.jdbc.batch_size=
μ μ΅μ μ ν΅ν΄ νκΊΌλ²μ INSERT/UPDATEλ₯Ό μ€νν ν¬κΈ°(μ°κΈ° μ§μ° μ μ₯μμ μ μ₯ν SQLμ μ΅λ κ°μ)λ₯Ό μ§μ ν μ μμ΅λλ€.
π λ³κ²½ κ°μ§(Dirty Checking)
EntityTransaction transaction = em.getTransaction();
transaction.begin()://νΈλμμ
μμ
//μν°ν° μ‘°ν -> μμν
Member memberA = em.find(Member.class, 1L);
memberA.setUsername("μ λν");
memberA.setAge(22);
transaction.commit();//νΈλμμ
컀λ°
μ μ½λλ₯Ό 보μλ©΄ update μΏΌλ¦¬κ° μμ΅λλ€.
μλ§λ μΌλ°μ μΌλ‘λ μ½λκ° λ€μκ³Ό κ°μμΌ ν κ²μ λλ€.
EntityTransaction transaction = em.getTransaction();
transaction.begin();//νΈλμμ
μμ
//μν°ν° μ‘°ν -> μμν
Member memberA = em.find(Member.class, 1L);
memberA.setUsername("μ λν");
memberA.setAge(22);
em.update(memberA);//μΆκ°
transaction.commit();//νΈλμμ
컀λ°
κ·Έλ¬λ JPA μμλ λ³λμ update μ½λκ° νμνμ§ μμ΅λλ€.
JPAλ 1μ°¨ μΊμμ λ€μ΄μλ μν°ν°κ° λ³κ²½λλ€λ©΄, κ·Έ λ³κ²½λ λ΄μ©μ κ°μ§νμ¬,νΈλμμ μ»€λ° μμ μ λ³κ²½λ λ΄μ©μ DBμ λ°μνλ€.
μ΄κ²μ΄ λ³κ²½κ°μ§μ λλ€.
π§ λ³κ²½ κ°μ§μ μ리
1μ°¨ μΊμμλ μ¬μ€ @Idμ Entity λ§κ³ λ νλμ 컬λΌμ΄ λ μ‘΄μ¬ν©λλ€.
λ°λ‘ "μ€λ μ·" μ΄λΌλ 컬λΌμ λλ€.
μν°ν°κ° 1μ°¨ μΊμμ μ μ₯λ λ, μ μ₯λλ μμ μ μνλ₯Ό μ€λ μ·μΌλ‘ λ§λ€μ΄ 1μ°¨ μΊμμ 보κ΄ν©λλ€.
νΈλμμ μ΄ μ»€λ°λλ μμ μ μν°ν°μ μ€λ μ·μ λΉκ΅νλλ°, μ΄λ λ§μ½ μν°ν°κ° λ³κ²½λμλ€λ©΄ λΉμ°ν μ€λ μ·κ³Ό μ°¨μ΄κ° μμ κ²μ΄κ³ , JPAλ μ΄λ₯Ό κ°μ§νμ¬ DBμ λ°μν©λλ€.
μ€μν κ²μ "컀λ°λλ μμ "μ "μν°ν°μ μ€λ μ·μ λΉκ΅"νλ€λ κ²μ λλ€.
λ°λΌμ 컀λ°λκΈ° μ μ μν°ν°λ₯Ό μμ νμ¬ μ¬μ©νμλ€κ°, 컀λ°λλ μμ μ λ€μ μμ볡ꡬ μν€λ©΄ update μΏΌλ¦¬κ° μ€νλμ§ μμ΅λλ€
μ½λλ₯Ό ν΅ν΄ μ΄ν΄λ³΄κ² μ΅λλ€.
EntityTransaction transaction = em.getTransaction();
transaction.begin();//νΈλμμ
μμ
//μν°ν° μ‘°ν -> μμν
Member memberA = em.find(Member.class, 1L);//μ΄ μμ μ username="μ λν", age=22
memberA.setUsername("λ°λ³΄");
System.out.println(memberA.getUsername());//λ°λ³΄ μΆλ ₯
memberA.setUsername("μ λν");
System.out.println(memberA.getUsername());//μ λν μΆλ ₯
transaction.commit();//νΈλμμ
컀λ°
μ μ½λλ₯Ό μ€ννλ©΄ update 쿼리λ λ°μνμ§ μμ΅λλ€.
μ¦ νλμ νΈλμμ λ΄μμλ μν°ν°λ₯Ό μ΄λ»κ² μμ νμ¬ μ¬μ©ν건 μκ΄μμ΄, νΈλμμ μ΄ μ»€λ°λλ μμ μ μν°ν°μ μνμ μ€λ μ·μ λΉκ΅νμ¬ λ°μλλ€λ κ²μ μκ³ λμ΄κ°μΌλ©΄ μ’κ² μ΅λλ€.
π Reference
'ποΈ Spring > JPA' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[JPA] νλμ μ»¬λΌ λ§€ν - @Enumerated (0) | 2021.12.14 |
---|---|
[JPA] νλμ μ»¬λΌ λ§€ν - @Column (0) | 2021.12.14 |
[JPA] μν°ν° 맀ν - @Entity, @Table (0) | 2021.12.13 |
[JPA] νλ¬μμ νλ¬μ νμ (FlushModeType) (0) | 2021.12.12 |
[JPA] μν°ν°μ μλͺ μ£ΌκΈ° - λΉμμ, μμ, μ€μμ, μμ (0) | 2021.12.12 |