ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๐Ÿ’ก์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ํŒฉํ† ๋ฆฌ์™€ ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €

  1. ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ํŒฉํ† ๋ฆฌ(Entity Manager Factory):
    • ์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „๋ฐ˜์— ๊ฑธ์ณ ์˜ค์ง ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ๋˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณต์žฅ ์—ญํ• ์„ ํ•œ๋‹ค. ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ํŒฉํ† ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ธ์…˜์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์„ค์ • ์ •๋ณด(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด, Dialect ๋“ฑ)๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
  2. ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €(Entity Manager):
    • ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋Š” ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ํŒฉํ† ๋ฆฌ์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋ฉฐ, ์‹ค์ œ๋กœ ์—”ํ‹ฐํ‹ฐ์™€ ๊ด€๋ จ๋œ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅ, ์ˆ˜์ •, ์‚ญ์ œ, ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋ฉฐ ๊ฐ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ๋ณ„๋กœ ์ƒ์„ฑ๋˜์–ด ์š”์ฒญ์ด ๋๋‚˜๋ฉด ํ๊ธฐ๋œ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํŠธ๋žœ์žญ์…˜๊ณผ ์ง์ ‘์ ์œผ๋กœ ๊ด€๋ จ์ด ์žˆ์œผ๋ฉฐ, ์—”ํ‹ฐํ‹ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

 

๐Ÿ’ก์˜์†์„ฑ ์ปจํ…์ŠคํŠธ

 

๐Ÿ’ป ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ž€?

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” '์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜๊ตฌ ์ €์žฅํ•˜๋Š” ํ™˜๊ฒฝ'์ด๋ผ๋Š” ๋œป์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์ด๋Š” ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ”๋กœ ์ €์žฅ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์ด์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ณด๊ด€ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ€์ƒ์˜ ๋ ˆ์ด์–ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

EntityManager.persist(entity); ์ฝ”๋“œ๋Š” ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํšŒ์› ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅํ•œ๋‹ค.

 

๐Ÿ’ป ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €์™€์˜ ๊ด€๊ณ„

์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €(Entity Manager)๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ฐ๊ฐ์˜ ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €์—๋Š” ๊ณ ์œ ์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค. ์ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋Š” ์—”ํ‹ฐํ‹ฐ๋“ค์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์—ฌ๊ธฐ์— ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ, ์กฐํšŒ, ์‚ญ์ œ ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. 

 

++) ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๊ฐ€ ๊ฐ™์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

๐Ÿ’ป ์—”ํ‹ฐํ‹ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ

์—”ํ‹ฐํ‹ฐ๋Š” ๋‹ค์Œ ๋„ค ๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค:

  • ๋น„์˜์†(New/Transient): ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ์ „ํ˜€ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ์ƒˆ๋กœ์šด ์ƒํƒœ์ด๋‹ค.

//๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ์ƒํƒœ(๋น„์˜์†)
Member member = new Member();
member.setId("member1");
member.setUsername("ํšŒ์›1");
  • ์˜์†(Managed): ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋œ ์ƒํƒœ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, em.persist(member);๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ด ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

//๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ์ƒํƒœ(๋น„์˜์†)
Member member = new Member();
member.setId("member1");
member.setUsername("ํšŒ์›1");

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

//๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ ์ƒํƒœ(์˜์†)
em.persist(member);
  • ์ค€์˜์†(Detached): ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์—ˆ๋‹ค๊ฐ€ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ์ด๋‹ค. ์ด ์ƒํƒœ๋Š” em.detach(member);, em.close();, ๋˜๋Š” em.clear();๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฐœ์ƒํ•œ๋‹ค.
//ํšŒ์› ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๋ถ„๋ฆฌ, ์ค€์˜์† ์ƒํƒœ
em.detach(member);
  • ์‚ญ์ œ(Removed): ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ญ์ œ๋œ ์ƒํƒœ์ด๋‹ค.
//๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•œ ์ƒํƒœ(์‚ญ์ œ)
em.remove(member);

 

๐Ÿ’ป ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ํŠน์ง•

  • ์‹๋ณ„์ž ๊ฐ’: ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋Š” ์‹๋ณ„์ž ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ SQL ์‹คํ–‰: ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๋Š” ์‹œ์ ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— SQL์„ ์‹คํ–‰ํ•˜์—ฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•œ๋‹ค.

 

๐Ÿ’ป ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ด์ 

  • 1์ฐจ ์บ์‹œ
  • ๋™์ผ์„ฑ(identity) ๋ณด์žฅ
  • ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ (transactional write-behind)
  • ๋ณ€๊ฒฝ ๊ฐ์ง€ (Dirty Checking)
  • ์ง€์—ฐ ๋กœ๋”ฉ (Lazy Loading)

1. 1์ฐจ ์บ์‹œ

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ 1์ฐจ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ์˜ ์˜์† ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. 1์ฐจ ์บ์‹œ๋Š” '@Id'๋กœ ๋งคํ•‘๋œ ํ•„๋“œ๋ฅผ ํ‚ค๋กœ ํ•˜๊ณ , ์—”ํ‹ฐํ‹ฐ ์ธ์Šคํ„ด์Šค ์ž์ฒด๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ€์ง€๋Š” Map ๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด,

//์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์„ฑํ•œ ์ƒํƒœ(๋น„์˜์†)
Member member = new Member();
member.setId("member1");
member.setUsername("ํšŒ์›1");

//์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†, 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋จ
em.persist(member);

//1์ฐจ ์บ์‹œ์—์„œ ์กฐํšŒ
Member findMember = em.find(Member.class, "member1");

 

์œ„ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด, 'Member' ์—”ํ‹ฐํ‹ฐ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋œ๋‹ค.

 

๊ทธ ํ›„, ์กฐํšŒ๋ฅผ ํ•˜๋ ค๋ฉด em.find๋กœ 1์ฐจ ์บ์‹œ์— ์žˆ๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋ฉด ๋œ๋‹ค.

 

๋งŒ์•ฝ 1์ฐจ ์บ์‹œ์— ์กฐํšŒํ•˜๋ ค๋Š” ๊ฐ’์ด ์—†๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

 

์˜ˆ๋ฅผ ๋“ค์–ด,

Member findMember2 = em.find(Member.class, "member2");

 

๋กœ "member2"๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•œ๋‹ค๋ฉด,

  1. ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ ์š”์ฒญ: em.find(Member.class, "member2") ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Member ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹๋ณ„์ž "member2"๋กœ ์กฐํšŒํ•œ๋‹ค.
  2. 1์ฐจ ์บ์‹œ ๊ฒ€์‚ฌ: ์š”์ฒญ๋œ ์—”ํ‹ฐํ‹ฐ๊ฐ€ 1์ฐจ ์บ์‹œ์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. member2๊ฐ€ ์บ์‹œ์— ์—†์œผ๋ฏ€๋กœ DB์กฐํšŒ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
  3. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ: member2๊ฐ€ 1์ฐจ ์บ์‹œ์— ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ง์ ‘ ์กฐํšŒ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  4. ์—”ํ‹ฐํ‹ฐ ์˜์†ํ™”: ์กฐํšŒํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Member ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค. ์ด ์‹œ์ ์—์„œ member2๋Š” ์˜์† ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.
  5. ์—”ํ‹ฐํ‹ฐ ๋ฐ˜ํ™˜: ์ƒ์„ฑ ๋ฐ ์ €์žฅ ๊ณผ์ •์„ ๊ฑฐ์นœ ์˜์†ํ™”๋œ Member ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ์— ๋˜ "member2"๋ฅผ ํ•œ ๋ฒˆ ๋” ์กฐํšŒํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ด๋ฏธ 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ DB์— ๊ฐ€์„œ ์กฐํšŒํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

2. ๋™์ผ์„ฑ ๋ณด์žฅ

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b); //๋™์ผ์„ฑ ๋น„๊ต true

 

JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ 1์ฐจ ์บ์‹œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฐจ์›์—์„œ ๋ชจ๋ฐฉํ•˜์—ฌ, ํŠนํžˆ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ์ฝ๊ธฐ(REPEATABLE READ) ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์ œ๊ณตํ•œ๋‹ค. 

๋”ฐ๋ผ์„œ a ์™€ b ๋ฅผ ๋™์ผ์„ฑ ๋น„๊ตํ•˜๋ฉด true๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

3. ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ

JPA์—์„œ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ(transactional write-behind)์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์˜ ํšจ์œจ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ณ  ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ด๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์—”ํ‹ฐํ‹ฐ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜์ง€ ์•Š๊ณ , ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๋Š” ์‹œ์ ์— ์ผ๊ด„์ ์œผ๋กœ SQL์„ ์ „์†กํ•œ๋‹ค.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋Š” ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
transaction.begin(); // [ํŠธ๋žœ์žญ์…˜] ์‹œ์ž‘

em.persist(memberA);
em.persist(memberB);
//์—ฌ๊ธฐ๊นŒ์ง€ INSERT SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค.

//์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— INSERT SQL์„ ๋ณด๋‚ธ๋‹ค.
transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

 

๋จผ์ €, ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, 

 

์—”ํ‹ฐํ‹ฐ ๋“ฑ๋ก

 

  • 'em.persist(memberA)'์™€  'em.persist(memberB)'๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๋“ค์˜ INSERT SQL์€ ์ฆ‰์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ „์†ก๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋Œ€์‹ , ์ด SQL๋ฌธ๋“ค์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด์˜ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์ €์žฅ๋œ๋‹ค.

 

์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” 1์ฐจ ์บ์‹œ์™€ ํ•จ๊ป˜ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์ด ์ €์žฅ์†Œ๋Š” ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ „์†กํ•ด์•ผ ํ•  ๋ชจ๋“  SQL ๋ช…๋ น์„ ๋ชจ์€๋‹ค.

ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹

transaction.commit(); // ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹

 

  • ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๋Š” ์ˆœ๊ฐ„, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์ €์žฅ์†Œ์— ๋ชจ์ธ SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ผ๊ด„ ์ „์†กํ•œ๋‹ค.
  • ์ด ๊ณผ์ •์„ ํ”Œ๋Ÿฌ์‹œ(flush)์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋™๊ธฐํ™”ํ•œ๋‹ค.

์“ฐ๊ธฐ ์ง€์—ฐ์˜ ์žฅ์ 

์“ฐ๊ธฐ ์ง€์—ฐ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์ ์„ ์ œ๊ณตํ•œ๋‹ค.

  • ์„ฑ๋Šฅ ์ตœ์ ํ™”: ์—ฌ๋Ÿฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ•œ ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ „์†กํ•จ์œผ๋กœ์จ ๋„คํŠธ์›Œํฌ ๋น„์šฉ๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ถ€ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ์šฉ์ด์„ฑ: ๊ฐœ๋ฐœ์ž๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์„ธ๋ถ€์ ์ธ ์ž‘์—…์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ , ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๋งŒ ๊ด€๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. ๋ชจ๋“  ๋ณ€๊ฒฝ์€ ํŠธ๋žœ์žญ์…˜์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋  ๋•Œ๋งŒ ๋ฐ˜์˜๋œ๋‹ค.

4. ๋ณ€๊ฒฝ ๊ฐ์ง€ (Dirty Checking)

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [ํŠธ๋žœ์žญ์…˜] ์‹œ์ž‘

// ์˜์† ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ
Member memberA = em.find(Member.class, "memberA");

// ์˜์† ์—”ํ‹ฐํ‹ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ •
memberA.setUsername("hi");
memberA.setAge(10);

//em.update(member) ์ด๋Ÿฐ ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•˜์ง€ ์•Š์„๊นŒ?

transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

 

์—”ํ‹ฐํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ ์ž ํ•  ๋•Œ, ์ˆ˜์ •ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ ์„ค์ •ํ•œ ํ›„์— "em.update(member)" ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. 

๊ทธ๋Ÿฌ๋‚˜ JPA๋ฅผ ์ด์šฉํ•˜๋ฉด ์—”ํ‹ฐํ‹ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ em.persist() ๋˜๋Š” em.update()๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•„๋„ DB์— ๋ณ€๊ฒฝ์ด ๋ฐ˜์˜๋œ๋‹ค. 

 

 

์˜์† ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ ๋ฐ ์ˆ˜์ •

  • ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•œ๋‹ค. 
  • ์กฐํšŒ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

์Šค๋ƒ…์ƒท ์ €์žฅ

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ์›๋ž˜ ์ƒํƒœ(์Šค๋ƒ…์ƒท)๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์ €์žฅํ•œ๋‹ค. 
  • ์Šค๋ƒ…์ƒท์ด๋ž€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๋ณด๊ด€ํ•  ๋•Œ, ์ตœ์ดˆ ์ƒํƒœ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ์ €์žฅํ•ด๋‘” ๊ฒƒ์ด๋‹ค. ์ฆ‰ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ฒ˜์Œ ๋กœ๋“œ๋  ๋•Œ ์ƒ์„ฑ๋œ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ๋ฐ ํ”Œ๋Ÿฌ์‹œ

  • ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๋Š” ์‹œ์ ์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ํ”Œ๋Ÿฌ์‹œ๋˜๋ฉฐ, ๋ณ€๊ฒฝ๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์Šค๋ƒ…์ƒท๊ณผ ๋น„๊ตํ•œ๋‹ค.
  • ๋ณ€๊ฒฝ์ด ๊ฐ์ง€๋˜๋ฉด, ์ˆ˜์ •๋œ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์ ์ ˆํ•œ SQL ์—…๋ฐ์ดํŠธ ๋ช…๋ น์ด ์ƒ์„ฑ๋˜์–ด ์“ฐ๊ธฐ ์ง€์—ฐ SQL์ €์žฅ์†Œ์— ์ถ”๊ฐ€๋œ๋‹ค.
  • ์ €์žฅ์†Œ์˜ SQL์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ „์†ก๋˜์–ด ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋œ๋‹ค.

๐Ÿ’กํ”Œ๋Ÿฌ์‹œ

 

ํ”Œ๋Ÿฌ์‹œ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜๋Š” ์ค‘์š”ํ•œ ๊ณผ์ •์ด๋‹ค.

์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด JPA๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•œ๋‹ค. 

๐Ÿ’ป  ํ”Œ๋Ÿฌ์‹œ์˜ ์ฃผ์š” ๊ณผ์ •

  1. ๋ณ€๊ฒฝ ๊ฐ์ง€(Dirty Checking):
    • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์Šค๋ƒ…์ƒท(์ตœ์ดˆ ์ €์žฅ๋œ ์ƒํƒœ)๊ณผ ๋น„๊ตํ•œ๋‹ค.
    • ๋ณ€๊ฒฝ๋œ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด, ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ์ˆ˜์ • SQL์„ ์ƒ์„ฑํ•˜์—ฌ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ๋“ฑ๋กํ•œ๋‹ค.
  2. ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ ์ฒ˜๋ฆฌ:
    • ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์ €์žฅ๋œ ๋ชจ๋“  SQL(๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œ)์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ „์†กํ•œ๋‹ค.
    • ์กฐํšŒ ์ฟผ๋ฆฌ๋Š” ์ €์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ, ํ•„์š” ์‹œ ์ฆ‰์‹œ ์ˆ˜ํ–‰๋œ๋‹ค.

๐Ÿ’ป  ํ”Œ๋Ÿฌ์‹œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. em.flush() - ์ง์ ‘ ํ˜ธ์ถœ
    • 'EntityManager'์˜ 'flush()' ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์˜์†์„ฑ ์ปจํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ•์ œ๋กœ ํ”Œ๋Ÿฌ์‹œํ•œ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์—์„œ๋Š” ๋“œ๋ฌผ๊ฒŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ์ด๋‚˜ ํ…Œ์ŠคํŠธ ์‹œ์— ํ™œ์šฉ๋œ๋‹ค.
  2. ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ - ํ”Œ๋Ÿฌ์‹œ ์ž๋™ ํ˜ธ์ถœ
    • ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ ์ž๋™์œผ๋กœ ํ”Œ๋Ÿฌ์‹œ๊ฐ€ ์ˆ˜ํ–‰๋œ๋‹ค. ์ด๋Š” JPA๊ฐ€ ํŠธ๋žœ์žญ์…˜์˜ ์™„๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰๋œ๋‹ค.
  3. JPQL ์ฟผ๋ฆฌ ์‹คํ–‰ - ํ”Œ๋Ÿฌ์‹œ ์ž๋™ ํ˜ธ์ถœ
    • JPQL์ด๋‚˜ Criteria ์ฟผ๋ฆฌ ์‹คํ–‰ ์ „์— ์ž๋™์œผ๋กœ ํ”Œ๋Ÿฌ์‹œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Š” ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ€ ์ตœ์‹  ์ƒํƒœ๋ฅผ ๋ฐ˜์˜ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 'persist()'๋กœ ์˜์†ํ™”๋œ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ฟผ๋ฆฌ์— ํฌํ•จ๋˜๋„๋ก ํ•˜๊ธฐ์œ„ํ•ด ํ•„์š”ํ•˜๋‹ค.
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);

//์ค‘๊ฐ„์— JPQL ์‹คํ–‰
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();

๐Ÿ’ป  ํ”Œ๋Ÿฌ์‹œ ๋ชจ๋“œ ์˜ต์…˜

  • FlushModeType.AUTO (๊ธฐ๋ณธ๊ฐ’): ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹์ด๋‚˜ ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • FlushModeType.COMMIT: ์ปค๋ฐ‹ ์‹œ์—๋งŒ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ”Œ๋Ÿฌ์‹œ ๋ชจ๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ณธ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์œผ๋‚˜, ํŠน์ • ์ƒํ™ฉ์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋‚˜ ๋™์ž‘ ์ œ์–ด๋ฅผ ์œ„ํ•ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

em.setFlushMode(FlushModeType.COMMIT); // ํ”Œ๋Ÿฌ์‹œ ๋ชจ๋“œ๋ฅผ ์ปค๋ฐ‹ ์‹œ๋งŒ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์„ค์ •

 

๐Ÿ’ป  ํ”Œ๋Ÿฌ์‹œ๋Š” !!

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋น„์šฐ์ง€ ์•Š๋Š”๋‹ค.
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋™๊ธฐํ™”ํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜์ด๋ผ๋Š” ์ž‘์—… ๋‹จ์œ„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค. -> ์ปค๋ฐ‹ ์ง์ „์—๋งŒ ๋™๊ธฐํ™”ํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ’ก์ค€์˜์† ์ƒํƒœ

์ค€์˜์† ์ƒํƒœ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ฆฌํ•˜๋˜ ์˜์† ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ด€๋ฆฌ ๋ฒ”์œ„์—์„œ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

์ด ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ๋Š” ๋” ์ด์ƒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ, ์บ์‹ฑ, ์“ฐ๊ธฐ ์ง€์—ฐ, ๋ณ€๊ฒฝ ๊ฐ์ง€ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•  ์ˆ˜ ์—†๋‹ค.

 

๐Ÿ’ป  ์ค€์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•

Member member = em.find(Member.class, 150L);
member.setName("AAAA");

em.detach(member); //ํŠน์ • ์—”ํ‹ฐํ‹ฐ๋งŒ ์ค€์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜
em.clear(); //์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”
em.close(); //์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ข…๋ฃŒ

System.out.println(" ========== ");

tx.commit();

 

  1. ํŠน์ • ์—”ํ‹ฐํ‹ฐ ๋ถ„๋ฆฌ (em.detach(entity)):
    • 'EntityManager'์˜ 'detach()' ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํŠน์ • ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ค€์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜ํ•œ๋‹ค. ์ด๋Š” ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๊ด€๋ฆฌ์—์„œ ์ œ๊ฑฐํ•œ๋‹ค. 
     

em.detach(member)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด,

  1. detach(memberA) ํ˜ธ์ถœํ•œ๋‹ค.
  2. 1์ฐจ ์บ์‹œ์— memberA์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
  3. ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์—์„œ memberA ๊ด€๋ จ SQL์„ ์ œ๊ฑฐํ•œ๋‹ค.

์˜ ๊ณผ์ •์„ ๊ฑฐ์น˜๊ฒŒ ๋œ๋‹ค.

 

2. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์ดˆ๊ธฐํ™” (em.clear()):

  • 'clear()' ๋ฉ”์†Œ๋“œ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋˜ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ค€์˜์† ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”๋œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

3. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์ข…๋ฃŒ (em.close()):

  • 'close()' ๋ฉ”์†Œ๋“œ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ข…๋ฃŒํ•˜๊ณ , ์ด์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ค€์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜ํ•œ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์™„์ „ํžˆ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค.

 

๐Ÿ’ป  ์ค€์˜์† ์ƒํƒœ์˜ ํŠน์ง•

  • ์‹๋ณ„์ž ์œ ์ง€: ์ค€์˜์† ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ๋Š” ์˜์† ์ƒํƒœ์ผ ๋•Œ ํ• ๋‹น๋ฐ›์€ ์‹๋ณ„์ž ๊ฐ’์„ ์œ ์ง€ํ•œ๋‹ค.
  • ๊ธฐ๋Šฅ ์‚ฌ์šฉ ๋ถˆ๊ฐ€: 1์ฐจ ์บ์‹œ, ์“ฐ๊ธฐ ์ง€์—ฐ, ๋ณ€๊ฒฝ ๊ฐ์ง€, ์ง€์—ฐ ๋กœ๋”ฉ ๋“ฑ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ง€์—ฐ ๋กœ๋”ฉ ๋ถˆ๊ฐ€: ์ค€์˜์† ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ๋Š” ์ง€์—ฐ ๋กœ๋”ฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค. ์‹ค์ œ ๊ฐ์ฒด ๋Œ€์‹  ํ”„๋ก์‹œ๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ์ง€์—ฐ ๋กœ๋”ฉ์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ค€์˜์† ์ƒํƒœ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.