๐ค ์์์ฑ ์ปจํ ์คํธ๋ ์ผ์ข ์ JPA ์ปจํ ์ด๋ ์์์ ๋์ํ๋ entity์ ๋งฅ๋ฝ์ ๊ด๋ฆฌํ๋ ๊ฒ์ด๋ค. ์ด ์์์ entity๋ ์์ฑ๋๊ณ ์ง์์ง๊ณ ์กฐํ๋๋ค. ๊ทธ context ์์์ ๊ฐ์ฅ ์ค์ํ ์ญํ์ ํ๋ ๊ฒ์ด EntityManager ๊ฐ์ฒด์ด๋ค. ์ด ์ญํ์ ์์๋ณด๊ณ , EntityManager๊ฐ entity๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์์ Cache๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์์๋ณด์.
EntityManager
- EntityManager๋ JPA์์ ์ ์ํ๊ณ ์๋ Interface ์ด๋ค. persist merge remove find ๋ฑ๋ฑ ์ ์๋์ด์๋ค. ๊ทธ๋ฆฌ๊ณ ๊ตฌํ์ฒด๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํ๊ณ ์๊ธฐ ๋๋ฌธ์ Autowire๋ฅผ ์ด์ฉํด ์ฌ์ฉํ ์ ์๋ค.
- ์ฟผ๋ฆฌ๋ฉ์๋๋, simplejparepository ๋ฑ ๋ด๋ถ์ ์ธ ์ค์ ๋์์ entityManager๋ฅผ ํตํ์ฌ ์คํ๋๊ธฐ ๋๋ฌธ์ SpringDataJpa์์ ์ ๊ณตํ์ง ์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ฑฐ๋, ์ฑ๋ฅ๋ฌธ์ ๊ฐ ์์ด ๋ณ๋๋ก ์ปค์คํฐ ๋ง์ด์ง์ ํด์ผํ๋ฉด EntityManager๋ฅผ ๋ฐ์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
@SpringBootTest
public class EntityManagerTest {
@Autowired
private EntityManager entityManager;
@Test
void entityManagerTest() {
System.out.println(entityManager.createQuery("select u from User u").getResultList()); // entityManager์์ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค์ ์ฌ์ฉ
// userRepository.findAll(); ์ด๊ฑฐ์ ๊ฐ๋ค.
}
- ์์ฒ๋ผ ์ปค์คํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์ง๋ง, ์ด๋ฒ ๊ฐ์์์๋ EntityManager์ Cache๋ฅผ ๊ณต๋ถํ ๊บผ๋๊น ๋์ด๊ฐ์.
Entity ์บ์ ์์๋ณด์
- EntityManager์์ ์ฌ์ฉํ๋ Entity์บ์๋ ๋ญ๊น? ์์์ฑ ์ปจํ ์คํธ ๋ด์์ ์ํฐํฐ๋ค์ ๊ด๋ฆฌํ๊ณ ์๋ EntityManager์์๋ Cache๋ฅผ ๊ฐ์ง๊ณ ์๋์ ์ค์ ๋ก ์ฐ๋ฆฌ๊ฐ save๋ฉ์๋๋ฅผ ์คํ์ํค๋ ์์ ์ DB์ ๋ฐ์๋๋๊ฒ ์๋๋ค. ์ฆ, ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ์์์ฑ ์ปจํ ์คํธ๋ก ์ค์ DB์ฌ์ด์์ Data ๊ฐญ์ด ์ผ์ด๋๋ค๋ ๋ป์ด๋ค.
@Test
void cacheFindTest() {
System.out.println(userRepository.findByEmail("martin@fast.com"));
System.out.println(userRepository.findByEmail("martin@fast.com"));
System.out.println(userRepository.findByEmail("martin@fast.com"));
}
- ์ ์ฝ๋๋ฅผ Test ํ์
select user0_.id as id1_7_, user0_.created_at as created_2_7_, user0_.updated_at as updated_3_7_, user0_.email as email4_7_, user0_.gender as gender5_7_, user0_.name as name6_7_ from user user0_ where user0_.email=?
- ์ ์ฟผ๋ฆฌ๋ฅผ 3๋ฒ ๋๋ค. ์ด๋ฒ์๋ Transactional์ด๋ ธํ ์ด์ ์ ๊ฑธ๊ณ findById๋ฅผ ์คํ ํด ๋ณด์.
@SpringBootTest
@Transactional
public class EntityManagerTest {
@Test
void cacheFindTest() {
System.out.println(userRepository.findById(2L).get());
System.out.println(userRepository.findById(2L).get());
System.out.println(userRepository.findById(2L).get());
}
select
...
...
where
user0_.id=?
User(super=BaseEntity(createdAt=2022-02-11T16:44, updatedAt=2022-02-11T16:44), id=2, name=demis, email=demis@fast.com, gender=null)
User(super=BaseEntity(createdAt=2022-02-11T16:44, updatedAt=2022-02-11T16:44), id=2, name=demis, email=demis@fast.com, gender=null)
User(super=BaseEntity(createdAt=2022-02-11T16:44, updatedAt=2022-02-11T16:44), id=2, name=demis, email=demis@fast.com, gender=null)
- ์์๊ฐ์ด select๋ ํ๋ฒ ์คํ๋ฌ๋๋ฐ ๊ฒฐ๊ณผ๋ 3๊ฐ ๋์ค๋๊ฑธ ํ์ธํ ์ ์๋ค. ์์์ฑ ์ปจํ ์คํธ์์ ์กด์ฌํ๋ ์บ์๊ฐ ์ง์ ์ฒ๋ฆฌํ ๊ฒ์ด๋ค. ์ง์ง DB์ฟผ๋ฆฌ๋ฅผ ์กฐํํ์ง ์๊ณ ๋ง์ด๋ค.
- ์ฐ๋ฆฌ๊ฐ ๋ฐ๋ก ์บ์ ์ค์ ์ ํ์ง ์์์ง๋ง, ์์์ฑ ์ปจํ ์คํธ๋ด์์ ์๋์ผ๋ก ์ํฐํฐ์ ๋ํ ์บ์ฌ์ฒ๋ฆฌํ๋ ๊ฒ์ด JPA์ 1์ฐจ Cache์ฒ๋ฆฌ๋ผ๊ณ ํ๋ค.
- ๊ทธ๋ ๋ค๋ฉด findById๊ณผ findByEmail์์ 1์ฐจ Cache๊ฐ ์ ์ฉ๋๊ณ , ๋์ง ์๋๊ฒ์ ์ฐจ์ด๊ฐ ๋ญ๊น?
- 1์ฐจ ์บ์๋ Map ํํ๋ก ๋ง๋ค์ด ์ง๊ณ Key๋ Id๊ฐ value๋ ํด๋น ์ํฐํฐ๊ฐ ๋ค์ด์๋ค.
- Id๋ก ์กฐํํ๋ฉด ๋จผ์ ์์์ฑ ์ปจํ ์คํธ๋ด์ ์กด์ฌํ๋ 1์ฐจ ์บ์์ ์กฐํํด ๋ณด๊ณ ์์ผ๋ฉด DB์กฐํ์์ด ๋ฐ๋ก ๊ฐ์ ๋ฆฌํฐํด ์ค๋ค.
- ๊ฐ์ด ์์ผ๋ฉด ์ค์ ์ฟผ๋ฆฌ๋ก DB์กฐํํด์ 1์ฐจ์บ์์ ์ ์ฅํ๊ณ ๋ฆฌํดํด์ค๋ค.
- 1์ฐจ ์บ์๋ฅผ ์ฌ์ฉํจ์ ๋ฐ๋ผ์ ๊ธฐ๋ณธ์ ์ธ JPA ์กฐํ ์ฑ๋ฅ์ด ์ฌ๋ผ๊ฐ๋ค. ๊ฐ๋ฐ์๊ฐ ์ง์ ID๊ฐ์ ์ฌ์ฉํด์ ์กฐํํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๋ค. findById(2L) ๊ฐ์๊ฑฐ ๋ง์ด๋ค.
- JPA ํน์ฑ์ ID๊ฐ์ ์ด์ฉํ ์กฐํ๊ฐ ๋น๋ฒํ๊ฒ ์ผ์ด๋๋ค. update๋ delete๊ฐ์๊ฑฐ ๋ง์ด๋ค. ๊ทธ๋์ ํด๋น ๋ก์ง์ ์ฑ๋ฅ์ ํ๊ฐ ์ผ์ด๋๋ค. ์ด๋ 1์ฐจ ์บ์๋ฅผ ํ์ฉํด์ ์ฑ๋ฅ์ ํ๋ฅผ ์ค์ด๊ธฐ ์ํ ๋์ฑ ์ด ๋๋ค.
@Test
void cacheFindTest() {
userRepository.deleteById(1L);
}
Hibernate:
select
...
...
from
user user0_
left outer join
user_history userhistor1_
on user0_.id=userhistor1_.user_id
where
user0_.id=?
Hibernate:
update
review
set
user_id=null
where
user_id=?
Hibernate:
delete
from
user
where
id=?
- ์ ์ฒ๋ผ JPA๋ด๋ถ์ ์ผ๋ก ID์ ๋ํ ์กฐํ๊ฐ ์ผ์ด๋ ๋๊ฐ ๋ง์์ ํ๋์ ํธ๋์ ์ ์ ์คํํ ๊ฒฝ์ฐ 1์ฐจ ์บ์๋ฅผ ์ฌ์ฉํ๋ฏ๋ก์จ ์ฑ๋ฅ์ ํ๋ฅผ ๋ฐฉ์งํ๋ค.
@Transactional
public class EntityManagerTest {
@Test
void cacheFindTest2() {
User user = userRepository.findById(1L).get();
user.setName("marrrrrrrtin");
userRepository.save(user);
System.out.println("---------------------");
user.setEmail("marrrrrrtin@fast.com");
userRepository.save(user);
}
- ์ ์ฒ๋ผ update๋ฅผ 2๋ฒ save๋ฅผ 2๋ฒ ํ์ฌ๋ ์์์ฑ ์ปจํ
์คํธ์ ์บ์๊ฐ ๊ฐ์ง๊ณ ์๋ค๊ฐ merge๋ฅผ ํด์ ํ๋ฒ์ ์ ์ฉํ๋ค. ๋ง์ฝ @Transactional์ด ๊ฑธ๋ ค์์ผ๋ฉด ์ต์ข
merge๋ฅผ ํ Data์ DB๋ ์ฐจ์ด๊ฐ ์์ด์ ์ฟผ๋ฆฌ๋ฅผ ํธ์ถํ์ง ์์๊ฒ์ด๋ค.
(์ด๊ฒ ๋ง๋์ง ๋ชจ๋ฅด๊ฒ ๋ค....) - ์์์ฑ ์ปจํ ์คํธ์ cache๋ฅผ ์ ์ดํดํ๊ฒ ๋๋ฉด ์ด์ ์ ๋ฐฐ์ด flush์ ์ญํ๋ ์ดํดํ ์ ์๋ค. flush๋ ๋ชจ์ฌ์๋๊ฑธ ๋น์๋ธ๋ค๋ ๋ป์ด๋ค. ์ฆ, cache์ ์๋ ์ฟผ๋ฆฌ๋ฅผ DB์ ๊ฐ์ ๋ก ์ ์ฉ ์ํค๊ฒ ๋ค๋ ๊ฑฐ๋ค.
- ๊ทธ๋ ๋คํ๋๋ผ๊ณ flush๋ฅผ ๋จ๋ฐํ๋ฉด ์๋๋ค. cache์ ์ญํ์ ๋ฌดํจํ ์ํค๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ ํ๊ฐ ์ผ์ด๋ ์ ์๋ค.
- ์ ์ฟผ๋ฆฌ์ save ๋ฐ์ "userRepository.flush();"๋ฅผ ๊ฐ๊ฐ ์ ๋ ฅํ๋ฉด insert๋ updateํ ๋ history์ ์ ์ฅํ๋ ์ฟผ๋ฆฌ๋ 2๋ฒ ํธ์ถํ๊ฒ ๋๋๊ฒ ์ฒ๋ผ ๋ง์ด๋ค.
- cache์ง์ง ์ด๋ ต๋ค. ๋ด๊ฐ saveํ ๋ ค๊ณ saveํ๋๋ฐ save๋ฅผ ์ํด... ๊ทธ๋ผ ์์์ฑ ์ปจํ
์คํธ์ DB๊ฐ ๋๊ธฐํ ๋๋ ์์ ์ ์ธ์ ์ผ๊น?
- ์ฒซ ๋ฒ์งธ๋ก๋ flush()๋ฉ์๋๊ฐ ํธ์ถ๋ ๋. ๋๊ธฐํ ๋๋ค.
- ๋ ๋ฒ์งธ๋ก๋ ํธ๋์ ์ ์ด ๋๋์ commit ๋ ๋์ด๋ค.
- ๋ง์ง๋ง์ผ๋ก id๊ฐ์ด ์๋ JPQL ์ฟผ๋ฆฌ๊ฐ ์คํ๋ ๋ AutoFlush๊ฐ ๋ฐ์ํ๋ค. ๋ณต์กํ ์ฟผ๋ฆฌ๊ฐ ์ผ์ด๋๋ฉด Autoflush๊ฐ ๋๋ค๊ณ ์๊ฐํ๋ฉด๋๋ค.
'Dev > JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JPA์์ Transaction์ ์ ํ (0) | 2022.03.02 |
---|---|
์์์ฑ ์ปจํ ์คํธ(Entity LifeCycle) (0) | 2022.03.02 |
JPA M:N ์ฐ๊ด๊ด๊ณ (0) | 2022.03.02 |
JPA ์ฐ๊ด๊ด๊ณ ์ดํด๋ณด๊ธฐ(1:1) (0) | 2022.03.02 |
JPA ์ฐ๊ด๊ด๊ณ (N:1) (0) | 2022.03.02 |