μ›Ή 개발/Spring Boot

[κΉ€μ˜ν•œ_μžλ°” ORM ν‘œμ€€ JPA ν”„λ‘œκ·Έλž˜λ° - 기본편] 2. μ˜μ†μ„± 관리

shj718 2022. 6. 8. 17:29

🌿 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλž€?

- μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλž€ Entityλ₯Ό 영ꡬ μ €μž₯ν•˜λŠ” ν™˜κ²½μ΄λ‹€. EntityManagerλ₯Ό ν†΅ν•΄μ„œ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ ‘κ·Όν•œλ‹€.

μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” νŠΈλžœμž­μ…˜ λ‹¨μœ„λΌλŠ” 것이 μ€‘μš”ν•˜λ‹€.

EntityManager.persist(entity);

- Entityκ°€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—μ„œ κ΄€λ¦¬λ˜λŠ” μƒνƒœλ₯Ό μ˜μ†μ΄λΌκ³  ν•˜κ³ , κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μƒˆλ‘œμš΄ μƒνƒœλ₯Ό λΉ„μ˜μ†μ΄λΌκ³  ν•œλ‹€.

persist()λ₯Ό ν•˜λ©΄, μ˜μ† μƒνƒœκ°€ λœλ‹€. 즉, persist()λŠ” 사싀 μ—”ν‹°ν‹°λ₯Ό DB에 μ €μž₯ν•˜λŠ” ν•¨μˆ˜κ°€ μ•„λ‹ˆλΌ, μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— λ„£λŠ” ν•¨μˆ˜μ΄λ‹€. μ—”ν‹°ν‹°κ°€ μ‹€μ œλ‘œ DB에 μ €μž₯λ˜λŠ” μ‹œμ μ€ νŠΈλžœμž­μ…˜μ΄ commit() 될 λ•Œμ΄λ‹€.

 

🌿 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 이점

- 1μ°¨ μΊμ‹œ (ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ)

Ex 1)

Member member = new Member();
member.setId(103L);
member.setName("HelloJPA");
entityManager.persist(member);
            
Member findMember3 = entityManager.find(Member.class, 103L);

μ΄λ ‡κ²Œ persist()λ₯Ό ν•˜λ©΄, 1μ°¨ μΊμ‹œμ— μ—”ν‹°ν‹°κ°€ μ €μž₯λœλ‹€. λ”°λΌμ„œ ν•΄λ‹Ή νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ find()λ₯Ό μ‹€ν–‰ν•˜λ©΄, DB에 SELECT 쿼리λ₯Ό 날리지 μ•Šκ³ , 1μ°¨ μΊμ‹œμ—μ„œ μ—”ν‹°ν‹°λ₯Ό μ°Ύμ•„μ˜¨λ‹€.

 

Ex 2)

Member findMember1 = entityManager.find(Member.class, 101L);
Member findMember2 = entityManager.find(Member.class, 101L);

μ΄λ ‡κ²Œ μ—°μ†μ μœΌλ‘œ find()λ₯Ό ν•˜λŠ” κ²½μš°μ—λ„ 첫번째 find()μ—μ„œλŠ” DB에 SELECT 쿼리λ₯Ό λ‚ λ¦¬μ§€λ§Œ, λ‘λ²ˆμ§Έ find()μ—μ„œλŠ” DB에 μ ‘κ·Όν•˜μ§€ μ•Šκ³ , 1μ°¨ μΊμ‹œμ—μ„œ μ—”ν‹°ν‹°λ₯Ό κ°€μ Έμ˜¨λ‹€.

 

- μ˜μ† Entity의 동일성 보μž₯

Member a = em.find(Member.class, 100L); 
Member b = em.find(Member.class, 100L);
System.out.println(a == b); //동일성 비ꡐ true

 

- μ“°κΈ° 지연

persist()λ₯Ό ν•˜λ©΄ 1μ°¨ μΊμ‹œ 뿐만 μ•„λ‹ˆλΌ, μ“°κΈ° 지연 SQL μ €μž₯μ†Œμ—λ„ ν•΄λ‹Ή INSERT문이 μ €μž₯λœλ‹€.

μ €μž₯된 INSERT문듀은 νŠΈλžœμž­μ…˜μ΄ 컀밋할 λ•Œ DB에 μ‹€ν–‰λœλ‹€.

em.persist(memberA);
em.persist(memberB);
//μ—¬κΈ°κΉŒμ§€ INSERT SQL을 λ°μ΄ν„°λ² μ΄μŠ€μ— 보내지 μ•ŠλŠ”λ‹€.
//μ»€λ°‹ν•˜λŠ” μˆœκ°„ λ°μ΄ν„°λ² μ΄μŠ€μ— INSERT SQL을 보낸닀.
transaction.commit();

 

- λ³€κ²½ 감지

μ €λ²ˆ κΈ€μ—μ„œλ„ μ–ΈκΈ‰ν–ˆλ“―μ΄ Entity의 속성(Ex. name)을 λ³€κ²½ν•˜κ³ μž ν•  λ•Œ set()만 ν•΄μ£Όλ©΄ λœλ‹€. (= persistν•  ν•„μš” X)

μ΄λŠ” μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—μ„œ DB에 commit()ν•˜κΈ° 전에, 1μ°¨ μΊμ‹œμ— μžˆλŠ” μ—”ν‹°ν‹°μ˜ 처음 μƒνƒœ(findν•  λ‹Ήμ‹œμ˜ μƒνƒœ)와 λ§ˆμ§€λ§‰ μƒνƒœλ₯Ό λΉ„κ΅ν•˜λŠ” 과정을 거치기 λ•Œλ¬Έμ΄λ‹€.

Member findMember = entityManager.find(Member.class, 160L);
findMember.setName("Changed");

 

- Entity μ‚­μ œ

Member findMember = entityManager.find(Member.class, 160L);
entityManager.remove(findMember);

 

🌿 ν”ŒλŸ¬μ‹œ(Flush)λž€?

ν”ŒλŸ¬μ‹œλž€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ³€κ²½ λ‚΄μš©μ„ DB에 μ‹€μ œλ‘œ λ°˜μ˜ν•˜λŠ” 것이닀.

νŠΈλžœμž­μ…˜ commit()은 μžλ™μœΌλ‘œ ν”ŒλŸ¬μ‹œλ₯Ό ν˜ΈμΆœν•œλ‹€. JPQL 쿼리λ₯Ό μ‹€ν–‰ν•  λ•Œλ„ ν”ŒλŸ¬μ‹œλŠ” μžλ™μœΌλ‘œ ν˜ΈμΆœλœλ‹€. 직접 em.flush()둜 ν”ŒλŸ¬μ‹œλ₯Ό ν˜ΈμΆœν•  μˆ˜λ„ μžˆλ‹€.

ν”ŒλŸ¬μ‹œλŠ” μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλ₯Ό λΉ„μš°λŠ” 것이 μ•„λ‹ˆλΌ, μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ³€κ²½ λ‚΄μš©μ„ DB에 λ™κΈ°ν™”ν•˜λŠ” 것이닀.