JPA - ynjch97/YNJCH_WIKI GitHub Wiki

1. Persistence Framework

  • ์˜์†์„ฑ(Persistence) : ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜๋”๋ผ๋„ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์˜ ํŠน์„ฑ
  • JDBC ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๋ณต์žกํ•จ์ด๋‚˜ ๋ฒˆ๊ฑฐ๋กœ์›€ ์—†์ด ๊ฐ„๋‹จํ•œ ์ž‘์—…๋งŒ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๋™๋˜๋Š” ์‹œ์Šคํ…œ์„ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์•ˆ์ •์ ์ธ ๊ตฌ๋™์„ ๋ณด์žฅ
  • SQL Mapper์™€ ORM์œผ๋กœ ๊ตฌ๋ถ„๋จ
  • ์ฐธ๊ณ  https://gmlwjd9405.github.io/2018/12/25/difference-jdbc-jpa-mybatis.html

1-1. JDBC

  • JDBC๋Š” DB์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก Java์—์„œ ์ œ๊ณตํ•˜๋Š” API
  • ๋ชจ๋“  Java์˜ Data Access ๊ธฐ์ˆ ์˜ ๊ทผ๊ฐ„
  • ๋ชจ๋“  Persistence Framework๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ JDBC API๋ฅผ ์ด์šฉ
  • JDBC๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ž๋ฃŒ๋ฅผ ์ฟผ๋ฆฌํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณต

1-2. SQL Mapper์™€ ORM

  • ORM : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋งคํ•‘ํ•จ์œผ๋กœ์จ ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ SQL์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑ
  • SQL Mapper : SQL์„ ๋ช…์‹œํ•ด์ค˜์•ผ ํ•จ
  • ORM : ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ '๊ด€๊ณ„'๋ฅผ Object์— ๋ฐ˜์˜ํ•˜์ž๋Š” ๊ฒƒ์ด ๋ชฉ์ 
  • SQL Mapper : ๋‹จ์ˆœํžˆ ํ•„๋“œ๋ฅผ ๋งคํ•‘์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ชฉ์ 

1-3. SQL Mapper

  • SQL <โ€” ๋งคํ•‘ โ€”> Object ํ•„๋“œ
  • SQL Mapper๋Š” SQL ๋ฌธ์žฅ์œผ๋กœ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃธ
  • Ex) Mybatis, JdbcTempletes ๋“ฑ

1-3-1. Mybatis

  • JDBC๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ƒ๋‹น ๋ถ€๋ถ„์˜ ์ฝ”๋“œ์™€ ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ • ๋ฐ ๊ฒฐ๊ณผ ๋งคํ•‘์„ ๋Œ€์‹ ํ•ด์คŒ
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค record์— ์›์‹œ ํƒ€์ž…๊ณผ Map ์ธํ„ฐํŽ˜์ด์Šค, ์ž๋ฐ” POJO๋ฅผ ์„ค์ •ํ•ด์„œ ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•ด xml๊ณผ Annotation ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • SQL์— ๋Œ€ํ•œ ๋ชจ๋“  ์ปจํŠธ๋กค์„ ํ•˜๊ณ ์ž ํ• ๋•Œ ๋งค์šฐ ์ ํ•ฉ
  • SQL ์ฟผ๋ฆฌ๋“ค์ด ๋งค์šฐ ์ž˜ ์ตœ์ ํ™”๋˜์–ด ์žˆ์„ ๋•Œ์— ์œ ์šฉ
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ์„ค๊ณ„์— ๋Œ€ํ•œ ๋ชจ๋“  ์กฐ์ž‘์„ ํ•˜๊ณ ์ž ํ•  ๋•Œ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Œ

1-4. ORM(Object-Relational Mapping)

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ <โ€” ๋งคํ•‘ โ€”> Object ํ•„๋“œ
  • ORM(Object-relational mapping) : ๊ฐ์ฒด๋Š” ๊ฐ์ฒด๋Œ€๋กœ ์„ค๊ณ„ํ•˜๊ณ , ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Œ€๋กœ ์„ค๊ณ„
  • ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃธ
  • ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•ด์ฃผ๋Š” ๊ฒƒ
  • ORM์„ ์ด์šฉํ•˜๋ฉด SQL Query๊ฐ€ ์•„๋‹Œ ์ง๊ด€์ ์ธ ์ฝ”๋“œ(๋ฉ”์„œ๋“œ)๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Œ
  • ๊ฐ์ฒด ๊ฐ„ ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ SQL ์ž๋™ ์ƒ์„ฑ
  • Persistant API ๋ผ๊ณ ๋„ ํ•จ
  • Ex) Hibernate, JPA ๋“ฑ

1-4-1. JPA

  • Java Persistence API
  • ์ž๋ฐ” ORM ๊ธฐ์ˆ ์— ๋Œ€ํ•œ API ํ‘œ์ค€ ๋ช…์„ธ๋กœ, Java์—์„œ ์ œ๊ณตํ•˜๋Š” API
  • ORM์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ชจ์•„๋‘” ๊ฒƒ
  • JPA 2.1 ํ‘œ์ค€ ๋ช…์„ธ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด(= ORM Framework) : Hibernate, EclipseLink, DataNucleus, OpenJPA, TopLink Essentials ๋“ฑ
  • JPA๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ JDBC ์‚ฌ์ด์—์„œ ๋™์ž‘
  • ๊ฐœ๋ฐœ์ž๊ฐ€ JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, JPA ๋‚ด๋ถ€์—์„œ JDBC API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SQL์„ ํ˜ธ์ถœํ•˜์—ฌ DB์™€ ํ†ต์‹ 
  • ์ฐธ๊ณ  https://gmlwjd9405.github.io/2019/08/04/what-is-jpa.html JPA ์ €์žฅ ๊ณผ์ •

2. JPA

2-1. JPA ๊ตฌ์„ฑ ์š”์†Œ

  • javax.persistance ํŒจํ‚ค์ง€๋กœ ์ •์˜๋œ API ๊ทธ ์ž์ฒด
  • JPQL(Java Persistence Query Language)
  • ๊ฐ์ฒด/๊ด€๊ณ„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ

2-2. JPA ์žฅ์ 

  • SQL ์ค‘์‹ฌ์ ์ธ ๊ฐœ๋ฐœ์—์„œ ๊ฐ์ฒด ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœ
  • ๊ฐ„๋‹จํ•œ CRUD (๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์•Œ์•„์„œ DB UPDATE Query๊ฐ€ ์‹คํ–‰๋จ)
  • ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ฅผ ์™„์ „ํžˆ ์ž์œ ๋กญ๊ฒŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ง€์—ฐ ๋กœ๋”ฉ ์ „๋žต(Lazy Loading) ์‚ฌ์šฉ(๊ด€๋ จ๋œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ทธ ์‹œ์ ์— SELECT Query๋ฅผ ๋‚ ๋ ค์„œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ „๋žต)
  • ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ์กฐํšŒํ•œ ์—”ํ‹ฐํ‹ฐ๋Š” ๊ฐ™์Œ์„ ๋ณด์žฅ (๊ฒฐ๊ณผ์ ์œผ๋กœ, SQL์„ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰)
String memberId = "100";
Member member1 = jpa.find(Member.class, memberId); // DB์—์„œ ๊ฐ€์ ธ์˜ด
Member member2 = jpa.find(Member.class, memberId); // 1์ฐจ ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ด
member1 == member2; //๊ฐ™๋‹ค.
  • ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ(transactional write-behind) -> ๋ฒ„ํผ๋ง ๊ธฐ๋Šฅ
  • [ํŠธ๋žœ์žญ์…˜]์„ commit ํ•  ๋•Œ๊นŒ์ง€ INSERT, UPDATE, DELETE SQL์„ ๋ฉ”๋ชจ๋ฆฌ์— ์Œ“๋Š”๋‹ค
transaction.begin(); // [ํŠธ๋žœ์žญ์…˜] ์‹œ์ž‘
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// ์ด๋•Œ๊นŒ์ง€ INSERT SQL์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์žˆ๋‹ค๊ฐ€ ์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ชจ์•„์„œ ๋ณด๋ƒ„
transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

transaction.begin(); // [ํŠธ๋žœ์žญ์…˜] ์‹œ์ž‘
changeMember(memberA);
deleteMember(memberA);
DO_BUSINESS_LOGIC_PROCESS(); // ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰ ๋™์•ˆ DB ๋กœ์šฐ๋ฝ์ด ๊ฑธ๋ฆฌ์ง€ ์•Š์Œ
// UPDATE, DELETE SQL ์‹คํ–‰ํ•˜๊ณ  ์ปค๋ฐ‹
transaction.commit(); // [ํŠธ๋žœ์žญ์…˜] ์ปค๋ฐ‹

2-2-1. ์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading)

  • ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ๋•Œ ๋กœ๋”ฉํ•˜๋Š” ์ „๋žต
Member member = memberDAO.find(memberId);   // SELECT * FROM MEMBER
Team team = member.getTeam();
String teamName = team.getName();           // SELECT * FROM TEAM
  • memberDAO.find(memberId) : Member ๊ฐ์ฒด์— ๋Œ€ํ•œ SELECT ์ฟผ๋ฆฌ ์‹คํ–‰
  • member.getTeam() ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, team.getName() ๋กœ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๊ฑด๋“œ๋ฆฌ๋Š” ์‹œ์ ์— Team ๊ฐ์ฒด์— ๋Œ€ํ•œ SELECT ์ฟผ๋ฆฌ ์‹คํ–‰
  • Member์™€ Team ๊ฐ์ฒด ๊ฐ๊ฐ ๋”ฐ๋กœ ์กฐํšŒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋„คํŠธ์›Œํฌ๋ฅผ 2๋ฒˆ ํƒ€๊ฒŒ ๋จ

2-2-2. ์ฆ‰์‹œ ๋กœ๋”ฉ

  • JOIN SQL๋กœ ํ•œ ๋ฒˆ์— ์—ฐ๊ด€๋œ ๊ฐ์ฒด๊นŒ์ง€ ๋ฏธ๋ฆฌ ์กฐํšŒํ•˜๋Š” ์ „๋žต
  • ํ•ญ์ƒ ์—ฐ๊ด€๋œ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๊ฐ™์ด ๊ฐ€์ ธ์˜ด

2-3. Hibernate

  • JPA์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜
  • SQL์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ด์„œ JDBC API๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹˜ (Hibernate๊ฐ€ ์ง€์›ํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ๋Š” JDBC API๊ฐ€ ๋™์ž‘)
  • ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด(HQL, Hibernate Query Language)๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Œ
  • HQL : ์™„์ „ํžˆ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ด๋ฉฐ ์ƒ์†, ๋‹คํ˜•์„ฑ, ๊ด€๊ณ„๋“ฑ์˜ ๊ฐ์ฒด์ง€ํ–ฅ์˜ ๊ฐ•์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Œ
    • HQL ์ฟผ๋ฆฌ๋Š” ์ž๋ฐ” ํด๋ž˜์Šค์™€ ํ”„๋กœํผํ‹ฐ์˜ ์ด๋ฆ„์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„
    • ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
    • ํ”„๋กœ๊ทธ๋ž˜๋จธ์— ์˜ํ•ด ์ƒ์„ฑ๋˜๊ณ  ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ
    • SQL์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํŽ˜์ด์ง€๋„ค์ด์…˜์ด๋‚˜ ๋™์  ํ”„๋กœํŒŒ์ผ๋ง๊ณผ ๊ฐ™์€ ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
    • ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ” ์ž‘์—… ์‹œ ๋ช…์‹œ์ ์ธ join์„ ์š”๊ตฌํ•˜์ง€ ์•Š์Œ

2-3-1. Hibernate ์žฅ์ 

  • ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅ
  • ํ…Œ์ด๋ธ” ์ƒ์„ฑ, ๋ณ€๊ฒฝ, ๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์›€
  • ๋กœ์ง์„ ์ฟผ๋ฆฌ์— ์ง‘์ค‘ํ•˜๊ธฐ ๋ณด๋‹ค ๊ฐ์ฒด ์ž์ฒด์— ์ง‘์ค‘ ํ•  ์ˆ˜ ์žˆ์Œ
  • ๋น ๋ฅธ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

2-3-2. Hibernate ๋‹จ์ 

  • ๋งŽ์€ ๋‚ด์šฉ์ด ๊ฐ์‹ธ์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•Œ์•„์•ผ ํ•  ๊ฒƒ์ด ๋งŽ์Œ
  • ์ž˜ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐ์ดํ„ฐ ์†์‹ค ๋˜๋Š” ์„ฑ๋Šฅ์ƒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
โš ๏ธ **GitHub.com Fallback** โš ๏ธ