JPA ์‹œ์ž‘

JPA(Java Persistnce API) ๋ž€ ์ž๋ฐ” ์ง„์˜์—์„œ ORM(Object-Relational Mapping) ๊ธฐ์ˆ  ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ์ด๋‹ค. ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ DB ์‚ฌ์ด์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, SQL์— ์˜์กด์ ์ด์—ˆ๋˜ ๊ธฐ์กด ๋ฐฉ์‹์˜ ๋‹จ์ ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด ์ง€ํ–ฅ ๊ด€์ ์œผ๋กœ ๋ฐ”๋ผ๋ณด๊ณ  ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

๐Ÿงฉ ORM ?

  • ๊ธฐ์กด ๋ฐฉ์‹์œผ๋กœ ๊ฐ์ฒด์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ์˜ ๋ฌธ์ œ์ ์€ ํ…Œ์ด๋ธ”์— ๋งž์ถฐ์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ CRUDํ•  ๋•Œ๋งˆ๋‹ค ์ˆ˜๋งŽ์€ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ณต์žกํ•จ์ด ์žˆ์—ˆ๋‹ค.

  • ๋งŒ์•ฝ ์ž๋ฐ” ์ปฌ๋ ‰์…˜์— ์ €์žฅํ•˜๋“ฏ์ด CRUD ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ›จ์”ฌ ๊ฐ„ํŽธํ•œ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ด์งˆ ๊ฒƒ์ด๋‹ค.

  • ๊ฐ์ฒด๋Š” ๊ฐ์ฒด๋Œ€๋กœ ์„ค๊ณ„ํ•˜๊ณ , ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Œ€๋กœ ์„ค๊ณ„ํ•˜๊ณ , ORM ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ค‘๊ฐ„์—์„œ ๊ทธ ๋‘˜์„ ๋งคํ•‘ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • JPA ๋Š” ์ž๋ฐ” ์ง„์˜์—์„œ ORM ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฉฐ, ํ•˜์ด๋ฒ„๋„ค์ดํŠธ(Hibernate)๊ฐ€ ๊ตฌํ˜„์ฒด๋กœ์„œ JPA์˜ ํ‘œ์ค€ ๋ช…์„ธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.

๐Ÿงฉ JPA์™€ CRUD

  • JPA ๋Š” ์ž๋ฐ” ์ปฌ๋ ‰์…˜์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋“ฏ์ด (๋งˆ์น˜ list.add() ๋กœ ์ €์žฅํ•˜๋“ฏ์ด) CRUD ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
CRUD๋ฉ”์„œ๋“œ
Cjpa.persist(member)
RMember member = jpa.find(memberId)
Umember.setName(โ€œ๋ณ€๊ฒฝํ•  ์ด๋ฆ„โ€)
Djpa.remove(member)

๐Ÿงฉ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ธฐ๋Šฅ

  • JPA ๋Š” ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ 1์ฐจ ์บ์‹œ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๋™์ผ์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค)

  • ์“ฐ๊ธฐ ์ง€์—ฐ : ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•  ๋•Œ ๊นŒ์ง€ SQL ์ฟผ๋ฆฌ๋ฌธ์„ ๋ชจ์•„๋’€๋‹ค๊ฐ€ ์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ํ•œ๋ฒˆ์— ์ „์†กํ•œ๋‹ค.

  • ์ง€์—ฐ ๋กœ๋”ฉ๊ณผ ์ฆ‰์‹œ ๋กœ๋”ฉ : ์ง€์—ฐ ๋กœ๋”ฉ์ด๋ž€ ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ ์‚ฌ์šฉ๋  ๋•Œ ์ฟผ๋ฆฌ๋ฌธ์„ ์‹คํ–‰ํ•˜์—ฌ ๋กœ๋”ฉํ•˜๋Š” ๊ฒƒ์„ ๋งํ•˜๋ฉฐ, ์ฆ‰์‹œ ๋กœ๋”ฉ์€ Join SQL๋กœ ํ•œ๋ฒˆ์— ์—ฐ๊ด€๋œ ๊ฐ์ฒด๊นŒ์ง€ ๋ฏธ๋ฆฌ ์กฐํšŒํ•ด๋‘๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

๐Ÿฅ ์ฝ”๋“œ๋กœ ์ดํ•ดํ•ด๋ณด์ž

package org.example;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        // EntityManagerFactory : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๋”ฉ ์‹œ์ ์— ๋”ฑ ํ•œ๋ฒˆ ์ƒ์„ฑ.
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // EntityManager : ํŠธ๋žœ์žญ์…˜์„ ํ•˜๋‚˜ ์‹คํ–‰ํ•  ๋•Œ ๋งˆ๋‹ค ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ๋ฒ„๋ฆฐ๋‹ค. ์“ฐ๋ ˆ๋“œ๊ฐ„์— ๊ณต์œ ํ•˜๋ฉด ์•ˆ ๋จ.
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        /**
         * JPA์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ๋ณ€๊ฒฝ์ด ๋๋‚˜๋ฉด ๋ฐ˜๋“œ์‹œ em.close() ๋กœ ์ข…๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.
         */
        try {
            /**
             * (C)
             * ๋น„์˜์† ์ƒํƒœ.
             */
           Member member = new Member();
           member.setId(1L);
           member.setName("Hello JPA");

            /**
             * ์˜์† ์ƒํƒœ.
             * persist ํ•ด์•ผ JPA ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์•ˆ์— member ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐ.
             * ์ปจํ…์ŠคํŠธ ์•ˆ์—์„œ 1์ฐจ ์บ์‹œ๋กœ ์ €์žฅ๋จ. (ํ‚ค : db pk , ๊ฐ’ : entity ๊ฐ์ฒด)
             */
           em.persist(member);

            /**
             * (R)
             * find ํ•˜๋ฉด JPA๋Š” ๋””๋น„๋ฅผ ์กฐํšŒํ•˜๋Š”๊ฒŒ ์•„๋‹Œ ์ปจํ…์ŠคํŠธ์˜ 1์ฐจ ์บ์‹œ๋ฅผ ๋จผ์ € ์กฐํšŒํ•จ.
             * ๋งŒ์•ฝ 1์ฐจ ์บ์‹œ์— ์—†๋‹ค๋ฉด ๊ทธ์ œ์•ผ ๋””๋น„๋ฅผ ์กฐํšŒํ•˜๊ณ , ์กฐํšŒํ•œ ๊ฐ’์„ 1์ฐจ ์บ์‹œ์— ์ €์žฅ ํ›„ ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
             */
           Member findMember = em.find(Member.class, 2L);

            /**
             * JPQL : ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
             * ์ค‘์š”ํ•œ ์ ์€ ๋””๋น„ ํ…Œ์ด๋ธ”์ด ์•„๋‹Œ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ง ๋‹ค๋Š” ์ ์ด๋‹ค.
             * ์•„๋ž˜ ์ฝ”๋“œ์—์„œ Member ๋Š” ํ…Œ์ด๋ธ”์ด ์•„๋‹Œ ์ž๋ฐ” ํด๋ž˜์Šค์ด๋‹ค. (ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Member.class ๋ฅผ ๋ช…์‹œํ•จ)
             */
           List<Member> result = em.createQuery("select m from Member as m", Member.class)
                   .setFirstResult(0)
                   .setMaxResults(10)
                   .getResultList();
           for (Member member : result) {
               System.out.println("member : " + member.getName());
           }

            /**
             * (U)
             * JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์•ˆ์— ์žˆ๋Š” ๊ฐ์ฒด๋Š” JPA๊ฐ€ ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
             * ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ฐ”๋กœ(์ž๋™์œผ๋กœ) DB์— ๋ฐ˜์˜ํ•œ๋‹ค.
             */
           findMember.setName("Bye JPA");

            /**
             * (D)
             */
           em.remove(findMember);

            /**
             * ์ปค๋ฐ‹ํ•ด์•ผ ์ฟผ๋ฆฌ๋ฌธ์ด ์‹คํ–‰๋˜๋ฉฐ,
             * ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๋ฉด ๋ฐ˜๋“œ์‹œ em(entity manager)๋ฅผ ๋‹ซ์•„์•ผ ํ•œ๋‹ค.
             */
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}