Spring/jpa

[JPA] 엔티티 매니저 팩토리, 엔티티 매니저, 트랜잭션

라임온조 2023. 2. 9. 11:25

1. 엔티티 매니저 팩토리

1) 개념

엔티티 매니저를 만드는 공장

2) 특징

  • JPA를 시작하려면 persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성해야 함
    이때 Persistence 클래스를 사용함. 이 클래스는 persistence.xml에서 이름이 ""인 영속성 유닛을 찾아서 엔티티 매니저 팩토리를 생성해서 JPA를 사용할 수 있게 준비함
  • 엔티티 매니저 팩토리 생성 비용이 큼. persistence.xml에서 설정정보를 읽어서 jpa동작시키기 위한 객체를 만들고, jpa 구현체에 따라서는 데이터베이스 커넥션 풀도 생성하기 때문. 따라서, 엔티티 매니저 팩토리는 애프리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 함.
  • 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 됨
  • 데이터베이스 연결이 꼭 필요한 시점까지 커넥션을 얻지 않음. 보통 트랜잭션을 시작할 때 커넥션을 획득.

 

2. 엔티티 매니저

1) 개념

엔티티와 관련된 모든 일을 처리하는 엔티티를 관리하는 관리자

엔티티 매니저는 내부에 데이터베이스 커넥션을 유지하면서 Db와 통신, 엔티티 매니저가 가상의 DB라고 생각해도 됨

2) 특징

  • 엔티티 매니저 팩토리에서 엔티티 매니저를 생성
  • jpa 기능 대부분은 엔티티 매니저가 제공 - 엔티티를 DB에 등록 수정 삭제 조회 가능
    엔티티 매니저는 DB 커넥션과 밀접한 관계가 있으므로 스레드 간에 공유하거나 재사용하면 안 됨
  • 엔티티 매니저를 생성하는 비용은 크지 않음
  • 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 공유하면 안 됨

 

3. 트랜잭션 관리

JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 함. 트랜잭션 없이 하면 예외 발생
트랜잭션을 시작하려면 엔티티 매니저에서 트랜잭션 api를 받아와야 함.

 

4. 등록

엔티티를 저장하려면 엔티티 매니저의 persist 메소드에 저장할 엔티티를 넘겨주면 된다

JPA는 회원 엔티티의 매핑 정보(어노테이션)을 분석해서 sql을 자동으로 만들어 Db에 전달

 

5. 수정

JPA는 어떤 엔티티가 변경되었는지 추적하는 기능을 갖추고 있다. 따라서 엔티티의 값만 변경하면 update sql을 생성해서 db의 값을 변경한다

 

6. 한 건 조회

find 메소드는 조회할 엔티티 타입과 @Id로 데이터베이스 테이블의 기본 키와 매핑한 식별자 값으로 엔티티 하나를 조회

 

7. 목록 조회

테이블이 아닌 엔티티 객체를 대상으로 검색하려면 DB의 모든 데이터를 애플리케이션으로 불러와서 엔티티 객체로 변경한 다음 검색해야 하는데 이는 불가능하다.
애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL을 사용해야 한다
JPA는 JPQL이라는 쿼리 언어로 이런 문제를 해결한다

 

JPQL

1) 개념

SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어.

2) 특징

엔티티 객체를 대상으로 쿼리 한다. 따라서, 데이터베이스 테이블을 전혀 알지 못한다.

3) 동작

  • em.createQuery(JPQL, 반환 타입) 메소드를 실행해서 쿼리 객체 생성 후 쿼리 객체의 getResultList() 메소드를 호출하면 된다.
  • JPA는 JPQL을 분석해서 적절한 SQL을 만들어 DB에서 데이터를 조회한다.

8. 삭제

엔티티 매니저의 remove 메소드에 삭제하려는 엔티티를 넘겨준다

public class JpaStudyApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaStudyApplication.class, args);
// 엔티티 매니저 설정
	// 엔티티 매니저 팩토리 생성
    	
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpastudy");
        
     // 엔티티 매니저 생성
   
        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();

    }

public static void logic(EntityManager em) {
	String id = "id1";
    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);
  // 목록 조회
  	
    List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
  // 삭제
    em.remove(member);
}
}

 

'Spring > jpa' 카테고리의 다른 글

[JPA] 기본 키 매핑  (0) 2023.02.10
[JPA] 영속성 관리  (0) 2023.02.09
[JPA] persistence.xml  (0) 2023.02.09
[JPA] 엔티티 설계 어노테이션  (0) 2023.02.08
[JPA] 초기 세팅  (0) 2023.02.08