๐Ÿ’พ Database

[JPA]์˜์†์„ฑ ๊ด€๋ฆฌ : ๋‚ด๋ถ€ ๋™์ž‘ ๋ฐฉ์‹

์—ฐ_์šฐ๋ฆฌ 2022. 2. 21. 00:40
๋ฐ˜์‘ํ˜•

๋ชฉ์ฐจ

     

     

    ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ?

    ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๋…ผ๋ฆฌ์ ์ธ ๊ฐœ๋…์ด๋‹ค.

    ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•œ๋‹ค.

     

     - J2EE ๊ฐ™์€ ํ™˜๊ฒฝ

       ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €์™€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ 1:1 ๊ด€๊ณ„.

       ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ € ์•ˆ์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ 1๊ฐœ ์žˆ๋‹ค.

     

     - ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ 

       ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €์™€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ 1:N ๊ด€๊ณ„.

       ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด 1๊ฐœ์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•œ๋‹ค.

     

     

     

    ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๊ตฌ์กฐ

    ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ

    1. Mapํ˜•ํƒœ์˜ 1์ฐจ ์บ์‹œ ๊ณต๊ฐ„ : transaction.commit()์ „๊นŒ์ง€ ๊ฐ’์„ ๋ชจ์•„๋†“๋Š”๋‹ค.

    2. ์“ฐ๊ธฐ์ง€์—ฐ SQL์ €์žฅ์†Œ : transaction.commit()์ „๊นŒ์ง€ SQL๋ฌธ๋“ค์„ ๋ชจ์•„๋†“๋Š”๋‹ค.

     

    em.persist(memberA) ํ•˜๋ฉด

     - insert SQL๋ฌธ์„ ์“ฐ๊ธฐ์ง€์—ฐ SQL์ €์žฅ์†Œ์— ์ €์žฅํ•˜๊ณ ,

     - memberA์—”ํ‹ฐํ‹ฐ๋ฅผ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

     - memberA์—”ํ‹ฐํ‹ฐ์˜ ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“ค์–ด์„œ ๋ณด๊ด€ํ•œ๋‹ค. (๋‚˜์ค‘์— ์Šค๋ƒ…์ƒท๊ณผ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๊ณณ์„ ์ฒดํ‚นํ•œ๋‹ค)

     

    ์ด๋•Œ, @id๊ฐ’์€ DB์˜ id๊ฐ’๊ณผ ๊ฐ™๋‹ค. 

    ์—”ํ‹ฐํ‹ฐ์˜ @GeneratedValue ์ „๋žต์ด identity์ธ ๊ฒฝ์šฐ, DB์— ์ €์žฅ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” id๊ฐ€ null์ด๊ธฐ ๋•Œ๋ฌธ์—

    JPA๋Š” @GeneratedValue์ „๋žต์ด identity์ผ๋•Œ๋งŒ em.persist()๋ฅผ ํ•˜๋ฉด ๋ฐ”๋กœ insert SQL๋ฌธ์„ DB์— ์ „์†กํ•˜๊ณ 

    ๋ฐ›์€ id๊ฐ’์„ 1์ฐจ ์บ์‹œ์˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

     

     

     

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

    1. 1์ฐจ ์บ์‹œ์—์„œ ์กฐํšŒ

        em.persist(member)ํ•˜๋ฉด member๊ฐ€ 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋˜๊ณ 

        em.find(member)ํ•˜๋ฉด 1์ฐจ ์บ์น˜์— ์ €์žฅ๋œ member๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

        => DB๊นŒ์ง€ ๊ฐ€์ง€ ์•Š์•„๋„ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค!

     

        em.find(member2)ํ–ˆ์„ ๋•Œ 1์ฐจ ์บ์‹œ์— ์—†๋‹ค๋ฉด, ๊ทธ๋•Œ DB์—์„œ ์กฐํšŒํ•œ๋‹ค.

        DB์—์„œ ์กฐํšŒํ•œ ๊ฒฐ๊ณผ๋ฅผ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•˜๊ณ , 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋œ member2๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

     

        (ํ•˜์ง€๋งŒ, ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋Š” ๊ฐ ์š”์ฒญ๋งˆ๋‹ค ์ƒ์„ฑ๋˜์—ˆ๋‹ค๊ฐ€ ์‚ญ์ œ๋œ๋‹ค. ์š”์ฒญ์ด ์‚ด์•„์žˆ์„ ๋•Œ์—๋งŒ 1์ฐจ ์บ์‹œ์˜ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋‹ค)

     

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

        List<Member> memberList = new ArrayList<>();

        memberList.add(memberA);

        memberList.add(memberA);

        memberList.get(0) == memberList.get(1);

        => ๊ฐ์ฒด์ง€ํ–ฅ ๋ฆฌ์ŠคํŠธ์—์„œ ๊ฐ™์€ ๊ฐ’์„ ์ €์žฅํ•œ ๊ฒƒ์€ ๊ฐ™๋‹ค๊ณ  ๋ณธ๋‹ค. (๊ฐ™์€ ์ฐธ์กฐ์ด๊ธฐ๋•Œ๋ฌธ์—)

     

        Member memberA = em.find(Member.class, memberA.getId());

        Member memberB = em.find(Member.class, memberA.getId());

        memberA == memberB;

        => ๊ฐ™์€ ์‹๋ณ„์ž๋กœ ๊ฐ€์ ธ์˜จ ๊ฐ’์ด๋‹ˆ ๊ฐ™๋‹ค๊ณ  ํŒ๋‹จํ•œ๋‹ค.

     

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

        em.persist(membr)๋Š” ์ฆ‰์‹œ insert SQL๋ฌธ์„ DB์— ์ „์†กํ•˜์ง€ ์•Š๋Š”๋‹ค.

        ์ฟผ๋ฆฌ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์“ฐ๊ธฐ์ง€์—ฐ SQL์ €์žฅ์†Œ์— ์Œ“์•„๋†“๊ณ  ์žˆ๋‹ค๊ฐ€,

        transaction.commit()ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ชจ์•„๋†“์€ ์ฟผ๋ฆฌ๋ฅผ DB์— ๋ณด๋‚ธ๋‹ค (์ผ์ข…์˜ ๋ฒ„ํผ)

     

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

        ์—”ํ‹ฐํ‹ฐ๋ฅผ 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•  ๋•Œ, ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋˜‘๊ฐ™์ด ๋ณต์‚ฌํ•œ ์Šค๋ƒ…์ƒท์„ ์ €์žฅํ•œ๋‹ค.

        ์—”ํ‹ฐํ‹ฐ์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๊ฒŒ๋˜๋ฉด ์Šค๋ƒ…์ƒท๊ณผ ๋‹ฌ๋ผ์ง€๊ฒŒ๋˜๋‹ˆ, ์ด๊ฒƒ์„ ํ™•์ธํ•˜์—ฌ JPA๊ฐ€ ์•Œ์•„์„œ Update SQL๋ฌธ์„ ์ƒ์„ฑํ•œ๋‹ค.

     

        ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ• ๋•Œ์™€ ์œ ์‚ฌํ•˜๋‹ค.

        List<Member> memberList = new ArrayList<>();

        Member member = memberList.get(0);

        member.changeName("memberZ");

        //memberList.add(member);   => ์ˆ˜์ •ํ•œ ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ

     

        Member findMember = em.find(Member.class, "memberA");

        findMember.changeName("memberZ");   => ๊ฐ’๋งŒ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

     

    5. ์ง€์—ฐ๋กœ๋”ฉ (Lazy Loading)

     

     

     

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

    1. ๋น„์˜์† (new/transient)

        ๊ฐ์ฒด๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋œ ์ƒํƒœ. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ์ „ํ˜€ ๊ด€๊ณ„์—†๋Š” ์ƒํƒœ.

        Member member = new Member();

        member.setId("member1");

     

    2. ์˜์† (managed)

        ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๊ด€๋ฆฌ๋˜๋Š” ์ƒํƒœ

        em.persist(member) : ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ๋‹ค.

        em.find(member) : JPA๋Š” 1์ฐจ ์บ์‹œ๋ฅผ ๋จผ์ € ์‚ดํ”ผ๊ณ , 1์ฐจ ์บ์‹œ์— member๊ฐ€ ์—†๋‹ค๋ฉด DB์—์„œ ์กฐํšŒํ•œ๋‹ค. 
                                 DB์— ์กฐํšŒํ•œ ๊ฒฐ๊ณผ๋ฅผ 1์ฐจ ์บ์‹œ์— ๋จผ์ € ์ €์žฅํ•˜๊ณ , 1์ฐจ ์บ์‹œ์˜ ๊ฐ’์„ ๋‹ค์‹œ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

                                 ๋”ฐ๋ผ์„œ em.find()ํ• ๋•Œ๋„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ฌ๋ผ๊ฐ€๊ฒŒ๋œ๋‹ค.

     

    3. ์ค€์˜์† (detached)

        ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ

        em.detach(member) : ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ member๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

        em.clear() : ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋‚ด์šฉ์„ ๋ชจ๋‘ ์‚ญ์ œํ•œ๋‹ค.

     

    4. ์‚ญ์ œ (removed)

        ์‚ญ์ œ๋œ ์ƒํƒœ

        em.remove(member) : ์‹ค์ œ DB์—์„œ member์— ํ•ด๋‹น๋˜๋Š” ๋‚ด์šฉ์„ ์‚ญ์ œํ•œ๋‹ค.

     

     

     

     

    ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ
    ๋ฐ˜์‘ํ˜•
    • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
    • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
    • ํŠธ์œ„ํ„ฐ ๊ณต์œ ํ•˜๊ธฐ
    • ๊ตฌ๊ธ€ ํ”Œ๋Ÿฌ์Šค ๊ณต์œ ํ•˜๊ธฐ
    • ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ