Back-End/JPA(자바 ORM 표준 기술)

[JPA][JPA 시작] - JPA 애플리케이션 개발 시작

얄루몬 2022. 5. 26. 15:43

 

📖본 포스팅은 '자바 표준 ORM 기술 JPA - 김영한'님의 책을 보고 작성되었습니다.


목차
1. JPA 애플리케이션 시작 코드
2. 엔티티 매니저 설정
3. 트랜잭션 관리
4. 비지니스 로직

JPA 애플리케이션 시작 코드

package jpabook.jpashop;

import jpabook.jpashop.domain.member.Member;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.*;
import java.util.List;

public class JpaMain {
    public static void main(String[] args) {

        //엔티티 매니저 팩토리 - 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");

        //엔티티 매니저 - 생성
        EntityManager em = emf.createEntityManager();

        //트랜잭션 - 획득
        EntityTransaction tx = em.getTransaction();

        try{
            tx.begin(); //트랜잭션 - 시작
            logic(em); //비지니스 로직 실행
            tx.commit(); //트랜잭션 커밋
        } catch (Exception e){
            tx.rollback(); //트랜잭션 롤백
        } finally {
            em.close(); //엔티티 매니저 종료
        }
        emf.close(); //엔티티 매니저 팩토리 종료

    }

    //비지니스 로직
    private static void logic(EntityManager em) {

        String id = "yaloo";
        Member member = new Member();
        member.setId(id);
        member.setUsername("얄루");
        member.setAge(2);

        //등록
        em.persist(member);

        //수정
        member.setAge(20);

        //한 건 조회
        Member findMember = em.find(Member.class, id);
        System.out.println("findMember.getUsername() = " + findMember.getUsername() +", age = "+ findMember.getAge());

        //목록 조회
        List<Member> members = em.createQuery("select m from Member m", Member.class)
                        .getResultList();
        System.out.println("members.size= "+ members.size());

        //삭제
        em.remove(member);
    }
}

크게 3 부분으로 코드가 나뉘어 있다.

  • 엔티티 매니저 설정
  • 트랜잭션 관리
  • 비지니스 로직

엔티티 매니저 설정

엔티티 매니저 팩토리 생성

  • JPA를 시작하려면 persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성해야 한다.
  • 이때 Persistence 클래스를 사용하는데 이 클래스는 엔티티 매니저 팩토리를 생성해서 JPA를 사용할 수 있게 준비한다.
  • 이때 META-INF/Persistence.xml에서 이름이 설정한 값의 이름과 같은 영속성 유닛을 찾아서 엔티티 매니저 팩토리를 생성해준다.
  • 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해야 한다.
    • 생성 비용이 크기 때문이다.

엔티티 매니저 생성

엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다.

  • JPA의 기능은 대부분 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
  • 엔티티 매니저는 내부 데이터소스를 유지하며 데이터베이스와 통신한다.
    • 이러한 이유로 애플리케이션 개발자는 엔티티 매니저를 가상의 데이터베이스로 생각할 수 있다.
  • 참고
    • 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있어 스레드 간의 공유 & 재사용을 하면 안 된다.

종료

  • 엔티티 매니저는 사용이 종료됐다면 반드시 종료해주어야 한다.
  • 애플리케이션 종료 시 엔티티 매니저 팩토리도 종료해주어야 한다.

트랜잭션 관리

  • JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해주어야 한다.
  • 트랜잭션 없이 변경하게 되면 예외가 발생한다. 
  • 트랜잭션 시작을 위해서 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.

트랜잭션 코드 부분

//트랜잭션 - 획득
        EntityTransaction tx = em.getTransaction();

        try{
            tx.begin(); //트랜잭션 - 시작
            logic(em); //비지니스 로직 실행
            tx.commit(); //트랜잭션 커밋
        } catch (Exception e){
            tx.rollback(); //트랜잭션 롤백
        } finally {
            em.close(); //엔티티 매니저 종료
        }

트랜잭션 API를 사용해서 비지니스 로직이 정상 동작하면 트랜잭션을 커밋(Commit)하고 예외가 발생하면 트랜잭션을 롤백(Rollback)한다. (데이터 베이스의 특성때문)

비지니스 로직

회원 엔티티를 하나 생성한 뒤 다음 엔티티 매니저를 통해서 데이터 베이스에 등록, 수정, 조회, 삭제한다.

비스니스 로직 코드

//비지니스 로직
    private static void logic(EntityManager em) {

        String id = "yaloo";
        Member member = new Member();
        member.setId(id);
        member.setUsername("얄루");
        member.setAge(2);

        //등록
        em.persist(member);

        //수정
        member.setAge(20);

        //한 건 조회
        Member findMember = em.find(Member.class, id);
        System.out.println("findMember.getUsername() = " + findMember.getUsername() +", age = "+ findMember.getAge());

        //목록 조회
        List<Member> members = em.createQuery("select m from Member m", Member.class)
                        .getResultList();
        System.out.println("members.size= "+ members.size());

        //삭제
        em.remove(member);
    }

findMember = 얄루, age = 20

members.size = 1

  • 비지니스 로직이 엔티티 매니저를 통해 수행됨을 알 수 있다. 
  • 엔티티 매니저는 객체를 저장하는 가상의 데이터베이스처럼 보인다.

등록

  • 엔티티를 저장하려면 엔티티 매니저의 persist() 메소드에 저장할 엔티티를 넘겨주면 된다.
  • 엔티티 매니저에 저장하려는 객체를 넘겨주면 된다.

수정

  • JPA는 엔티티 변경 추적하는 기능이 있어서 set( ) 메서드를 사용해 엔티티 값만 변경하면 된다.
    • update()같은 메소드 호출하지 않아도 된다.
    • 엔티티 값만 변경해주면 UPDATE SQL을 생성해서 데이터 베이스 값을 변경해준다.

조회

  • 한 건 조회
    • Member findMember = em.find(Member.class, id);
    • find( )를 사용해서 조회할 엔티티 타입과 데이터베이스 테이블의 기본키와 매핑한 식별자 값으로 엔티티 하나를 조회하는 가장 단순한 조회 메서드이다.
    • 이 메서드를 호출하면 SELECT SQL을 생성해 데이터베이스에 결과를 조회한다.
      • 조회한 결과 값으로 엔티티를 생성해서 반환해준다.
  • JPQL
    • 검색의 경우엔 검색 조건이 포함된 SQL이 필요한데 이를 JPA가 해결한 방안이 JPQL이다.
    • JPQL은 엔티티 객체를 대상으로 쿼리한다. 쉽게 말해 클래스와 필드를 대상으로 쿼리한다.
      • JPQL은 대소문자 구분이 엄격하다.
    • SQL은 데이터 베이스 테이블을 대상으로 쿼리한다.
      • SQL은 대소문자 구분이 엄격하지 않다.

삭제

  • JPA는 DELETE SQL을 생성해서 삭제해준다.
    • 엔티티 삭제하려면 엔티티 매니저의 remove( ) 메소드에 삭제하려는 엔티티를 넘겨준다.