[JPA] 1.JPA ์†Œ๊ฐœ

 

0. ๋“ค์–ด๊ฐ€๋ฉฐ

JPA๊ฐ€ ์‹ค๋ฌด์—์„œ ์–ด๋ ค์šด ์ด์œ 

1) ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ” ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋งตํ•‘ํ•˜๊ณ  2) ์„ค๊ณ„ํ•˜๋Š” ๋ฒ•์„ ๋ชฐ๋ผ์„œ


1. SQL ์ค‘์‹ฌ์ ์ธ ๊ฐœ๋ฐœ์˜ ๋ฌธ์ œ์  

Application์€ ๊ฐ์ฒด์ง€ํ–ฅ

Database๋Š” ๊ด€๊ณ„ํ˜•

 

+ ์ƒํ’ˆ, ์ฃผ๋ฌธ๋งˆ๋‹ค CRUD๋ฅผ ๋‹ค ๋งŒ๋“ค์–ด์•ผํ•จ

+ ๊ฐ์ฒด์— ํ•„๋“œ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด ์ฟผ๋ฆฌ๋ฌธ์„ ๋‹ค ๊ณ ์ณ์•ผํ•จ

 

ํŒจ๋Ÿฌ๋‹ค์ž„์˜ ๋ถˆ์ผ์น˜

- ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ถ”์ƒํ™” / ์บก์Šํ™” / ์ •๋ณด์€๋‹‰ / ์ƒ์† / ๋‹คํ˜•์„ฑ ๋“ฑ ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์žฅ์น˜๋“ค์„ ์ œ๊ณต

 

๊ฐ์ฒด๋ฅผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ

[๊ฐ์ฒด] - [sql ๋ณ€ํ™˜] - [RDB]

sql ๋ณ€ํ™˜ = sql ๋งตํผ๊ฐ€ ๊ฐœ๋ฐœ์ž์˜ ์—ญํ• 

 

(a) <<< ์ƒ์†๊ด€๊ณ„ >>>

- Album ์ €์žฅ

1) ๊ฐ์ฒด ๋ถ„ํ•ด

2) INSERT INTO ITEM

3) INSERT INTO ALBUM

 

- Album ์กฐํšŒ

1) ๊ฐ๊ฐ์˜ ํ…Œ์ด๋ธ”์— ๋”ฐ๋ฅธ ์กฐ์ธ SQL ์ž‘์„ฑ

2) ๊ฐ๊ฐ์˜ ๊ฐ์ฒด ์ƒ์„ฑ

-> ์ƒ์ƒ๋งŒํ•ด๋„ ๋ณต์žก

 

๊ทธ๋ž˜์„œ DB ์ €์žฅํ•  ๊ฐ์ฒด์—๋Š” ์ƒ์† ๊ด€๊ณ„๋ฅผ ์“ฐ์ง€ ์•Š์Œ!!

 

์ž๋ฐ” ์ปฌ๋ ‰์…˜์— ์ €์žฅํ•œ๋‹ค๋ฉด?
list.add(album);

์ž๋ฐ” ์ปฌ๋ ‰์…˜์—์„œ ์กฐํšŒํ•˜๋ฉด? : ๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ํ›„ ๋‹คํ˜•์„ฑ ํ™œ์šฉ

Item item = list.get(albumId);

 

(b) <<< ์—ฐ๊ด€๊ด€๊ณ„ >>>

- ๊ฐ์ฒด๋Š” ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉ : member.getTeam()

- ํ…Œ์ด๋ธ”์€ ์™ธ๋ž˜ ํ‚ค๋ฅผ ์‚ฌ์šฉ : JOIN ON M.TEAM_ID = T.TEAM_ID

 

์•„๋ž˜์ฒ˜๋Ÿผ ๊ฐ์ฒด๋ฅผ ํ…Œ์ด๋ธ”์— ๋งž์ถ”์–ด ๋ชจ๋ธ๋ง

์•„๋ž˜๋Š” ๊ฐ์ฒด๋‹ค์šด ๋ชจ๋ธ๋ง

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ธ์„œํŠธ ์ฟผ๋ฆฌ / ์กฐํšŒ ๊ฐ€ ๊นŒ๋‹ค๋กœ์›Œ์ง

์ธ์„œํŠธ -> TEAM_ID ์นผ๋Ÿผ์„ ๋„ฃ์„๋•Œ member.getTeam().getId(); ์‹์œผ๋กœ ํ•ด์•ผํ•จ

์กฐํšŒ -> SQL JOIN์œผ๋กœ ๋ฉค๋ฒ„ ๊ฐ€์ ธ์™€์„œ ๋ฉค๋ฒ„ ํŒ€ ๊ฐ๊ฐ ๋„ฃ์–ด์ฃผ๊ณ  ๊ด€๊ณ„ ์„ค์ •๊นŒ์ง€ ํ•ด์„œ(member.setTeam(team))  return 

 

์ž๋ฐ” ์ปฌ๋ ‰์…˜์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค๋ฉด?

list.add(member);

Member member = list.get(memberId);

Team team = member.getTeam();

 

(c) <<< ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ >>>

- ๊ฐ์ฒด๋Š” ์ž์œ ๋กญ๊ฒŒ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค

 

์—”ํ‹ฐํ‹ฐ ์‹ ๋ขฐ ๋ฌธ์ œ

-> DAO์—์„œ member ๊ฐ์ฒด ๊ฐ€์ ธ์™”๋Š”๋ฐ ํ•ด๋‹น member๊ฐ์ฒด์—์„œ member.getOrder() ๋“ฑ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

-> DAO์—์„œ find ๋ฉ”์„œ๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์„ค๊ณ„๋˜์—ˆ๋Š”์ง€๋ฅผ ๋ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์„ ํ•˜๊ฒŒ๋จ

 

๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋”ฉํ•  ์ˆ˜๋Š” ์—†๋‹ค

- ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋™์ผํ•œ ํšŒ์› ์กฐํšŒ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ์ƒ์„ฑํ•œ๋‹ค๋ฉด memberDAO.getmember/member with order ๋“ฑ๋“ฑ ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค ๋งŒ๋“ค์–ด์ค˜์•ผํ•จ...

 

๊ณ„์ธตํ˜• ์•„ํ‚คํ…์ฒ˜ - ์ง„์ •ํ•œ ์˜๋ฏธ์˜ ๊ณ„์ธต ๋ถ„ํ• ์ด ์–ด๋ ค์›€

 

(d) <<< ๋น„๊ตํ•˜๊ธฐ >>>

๋˜‘๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด ๊ฐ๊ฐ ์ƒ์„ฑํ•ด์„œ ๋น„๊ตํ•˜๋ฉด ๋ถ„๋ช…ํžˆ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ผ๊ณ  ์ธ์‹ํ•œ๋‹ค

ํ•˜์ง€๋งŒ ์ž๋ฐ” ์ปฌ๋ ‰์…˜์—์„œ list.get(memberId)๋ผ๊ณ  ํ•ด์„œ ์ƒ์„ฑํ•œ ๋‘๊ฐœ์˜ member ๊ฐ์ฒด๋Š” ๋™์ผํ•˜๋‹ค!

 

๊ฒฐ๋ก ) ๊ฐ์ฒด๋‹ต๊ฒŒ ๋ชจ๋ธ๋ง ํ• ์ˆ˜๋ก ๋งตํ•‘ ์ž‘์—…๋งŒ ๋Š˜์–ด๋‚จ...

-> ๊ฐ์ฒด๋ฅผ ์ž๋ฐ” ์ปฌ๋ ‰์…˜์— ์ €์žฅํ•˜๋“ฏ์ด DB์— ์ €์žฅํ•  ์ˆ˜๋Š” ์—†์„๊นŒ?

 

= JPA(Java Persistentce API)


2. JPA ์†Œ๊ฐœ

JPA?

- Java Persistence API

- ์ž๋ฐ” ์ง„์˜์˜ ORM ๊ธฐ์ˆ  ํ‘œ์ค€

 

ORM?

- Object-relational mapping (๊ฐ์ฒด ๊ด€๊ณ„ ๋งตํ•‘)

- ๊ฐ์ฒด๋Š” ๊ฐ์ฒด๋Œ€๋กœ ์„ค๊ณ„

- ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Œ€๋กœ ์„ค๊ณ„

- ORM ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ค‘๊ฐ„์—์„œ ๋งตํ•‘

- ๋Œ€์ค‘์ ์ธ ์–ธ์–ด์—๋Š” ๋Œ€๋ถ€๋ถ„ ORM ๊ธฐ์ˆ ์ด ์กด์žฌ

 

JPA๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ JDBC ์‚ฌ์ด์—์„œ ๋™์ž‘

 

JPA ๋™์ž‘ - ์ €์žฅ, ์กฐํšŒ

์ €์žฅ
์กฐํšŒ

JPA ์†Œ๊ฐœ

EJB : ์—”ํ‹ฐํ‹ฐ ๋นˆ (์ž๋ฐ” ํ‘œ์ค€) -> ํ•˜์ด๋ฒ„๋„คํŠธ (์˜คํ”ˆ ์†Œ์Šค) -> JPA (์ž๋ฐ” ํ‘œ์ค€)

 

JPA๋Š” ํ‘œ์ค€ ๋ช…์„ธ

- ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ

- 2.1 ํ‘œ์ค€ ๋ช…์„ธ๋ฅผ ๊ตฌํ˜„ํ•œ 3๊ฐ€์ง€ ๊ตฌํ˜„์ฒด

- ํ•˜์ด๋ฒ„๋„ค์ดํŠธ, EclipseLink, DataNucleus

 

JPA๋ฅผ ์™œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

- SQL ์ค‘์‹ฌ์ ์ธ ๊ฐœ๋ฐœ์—์„œ ๊ฐ์ฒด ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœ

- ์ƒ์‚ฐ์„ฑ

- ์œ ์ง€๋ณด์ˆ˜

- ํŒจ๋Ÿฌ๋‹ค์ž„์˜ ๋ถˆ์ผ์น˜ ํ•ด๊ฒฐ

- ์„ฑ๋Šฅ

- ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์ถ”์ƒํ™”์™€ ๋ฒค๋” ๋…๋ฆฝ์„ฑ

- ํ‘œ์ค€

 

1) ์ƒ์‚ฐ์„ฑ - JPA์™€ CRUD

- ์ €์žฅ : jpa.persist(member)

- ์กฐํšŒ : Member member = jpa.find(memberId)

- ์ˆ˜์ • : member.setName("๋ณ€๊ฒฝํ•  ์ด๋ฆ„")

- ์‚ญ์ œ : jpa.remove(member)

 

2) ์œ ์ง€๋ณด์ˆ˜

- ๊ธฐ์กด: ํ•„๋“œ ๋ณ€๊ฒฝ์‹œ ๋ชจ๋“  SQL ์ˆ˜์ •

- JPA : ํ•„๋“œ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด๋จ, SQL์€ JPA๊ฐ€ ์ฒ˜๋ฆฌ

 

3) JPA์™€ ํŒจ๋Ÿฌ๋‹ค์ž„์˜ ๋ถˆ์ผ์น˜ ํ•ด๊ฒฐ

(a) JPA์™€ ์ƒ์†

[์ €์žฅ]

- ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•  ์ผ : jpa.persist(album);

- ๋‚˜๋จธ์ง„ JPA๊ฐ€ ์ฒ˜๋ฆฌ : INSERT INTO ITEM... / INSERT INTO ALBUM...

 

[์กฐํšŒ]

- ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•  ์ผ : Album album = jpa.find(Album.class, albumId);

- ๋‚˜๋จธ์ง„ JPA๊ฐ€ ์ฒ˜๋ฆฌ : SELECT I.*, A.* FROM ITEM I JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID

 

(b) JPA์™€ ์—ฐ๊ด€๊ด€๊ณ„

- ์—ฐ๊ด€๊ด€๊ณ„ ์ €์žฅ : member.setTeam(team); / jpa.persist(member);

 

(c) JPA์™€ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰

- ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ : Member member = jpa.find(Member.class, memberId); / Team team = member.getTeam();

 

์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ, ๊ณ„์ธต

class MemberService {
  ...
  public void process() {
    Member member = memberDAO.find(memberId);
    member.getTeam();
    member.getOrder();.getDelivery();
  }
}

 

(d) JPA์™€ ๋น„๊ตํ•˜๊ธฐ

String memberId = "100";
Member member1 = jpa.find(Member.class, memberId);
Member member2 = jpa.find(Member.class, memberId);

member1 == member2 //๊ฐ™๋‹ค

* ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ์กฐํšŒํ•œ ์—”ํ‹ฐํ‹ฐ๋Š” ๊ฐ™์Œ์„ ๋ณด์žฅ

 

4) JPA์˜ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ธฐ๋Šฅ

(a) 1์ฐจ ์บ์‹œ์™€ ๋™์ผ์„ฑ(identity)๋ณด์žฅ

- ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ๋Š” ๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ - ์•ฝ๊ฐ„์˜ ์กฐํšŒ ์„ฑ๋Šฅ ํ–ฅ์ƒ

- DB isolation level์ด Read Commit์ด์–ด๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Repeatable Read ๋ณด์žฅ

-> jpa.find ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋„ sql์กฐํšŒ ํ•œ๋ฒˆ๋งŒ ๋จ!!! (๊ฐ™์€ ํŠธ๋žœ์žญ์…˜์•ˆ์—์„œ)

 

(b) ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ(transactional write-behind)

[INSERT]

- ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ• ๋•Œ๊นŒ์ง€ INSERT SQL์„ ๋ชจ์Œ

- JDBC BATCH SQL ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด์„œ ํ•œ ๋ฒˆ์— SQL ์ „์†ก

transaction.begin(); //ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘

em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// ์—ฌ๊ธฐ๊นŒ์ง€ INSERT SQL ๋ณด๋‚ด์ง€ ์•Š์Œ

// ์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— INSERT SQL ๋ชจ์•„์„œ ๋ณด๋ƒ„
transaction.commit();

 

[UDPATE, DELETE]

- UPDATE, DELETE๋กœ ์ธํ•œ ๋กœ์šฐ(ROW)๋ฝ ์‹œ๊ฐ„ ์ตœ์†Œํ™”

- ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ UPDATE, DELETE SQL ์‹คํ–‰ํ•˜๊ณ  ๋ฐ”๋กœ ์ปค๋ฐ‹

transaction.begin();

changeMember(memberA);
deleteMember(memberB);
// ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰() - ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰ ๋™์•ˆ DB ๋กœ์šฐ ๋ฝ์ด ๊ฑธ๋ฆฌ์ง€ ์•Š์Œ

// ์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— UPDATE, DELETE SQL ๋ณด๋ƒ„
transaction.commit();

 

(c) ์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading), ์ฆ‰์‹œ ๋กœ๋”ฉ

- ์ง€์—ฐ ๋กœ๋”ฉ : ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ ์‚ฌ์šฉ๋  ๋•Œ ๋กœ๋”ฉ

- ์ฆ‰์‹œ ๋กœ๋”ฉ : JOIN SQL๋กœ ํ•œ๋ฒˆ์— ์—ฐ๊ด€๋œ ๊ฐ์ฒด๊นŒ์ง€ ๋ฏธ๋ฆฌ ์กฐํšŒ

 

์ง€์—ฐ๋กœ๋”ฉ

Member member = memberDAO.find(memberId); 
Team team = member.getTeam();
String teamName = team.getName(); // ์ด๋•Œ ํ”„๋ก์‹œ ์ดˆ๊ธฐํ™” (team๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์™€์„œ ๊ฐ’ ์ฑ„์›Œ์คŒ)

์ฆ‰์‹œ๋กœ๋”ฉ

Member member = memberDAO.find(memberId); // member team ๊ฐ™์ด ์“ด๋‹ค๊ณ  ์…‹ํŒ… ํ•ด๋‘๋ฉด ์ฆ‰์‹œ ๋กœ๋”ฉ(์กฐ์ธํ•ด์„œ ๊ฐ€์ ธ์˜ด)
Team team = member.getTeam();
String teamName = team.getName();

 

ORM์€ [๊ฐ์ฒด]์™€ [RDB] ๋‘ ๊ธฐ๋‘ฅ ์œ„์— ์žˆ๋Š” ๊ธฐ์ˆ 

 

  • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
  • ๋„ค์ด๋ฒ„ ๋ฐด๋“œ์— ๊ณต์œ ํ•˜๊ธฐ
  • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
  • ์นด์นด์˜ค์Šคํ† ๋ฆฌ ๊ณต์œ ํ•˜๊ธฐ