JPA 찍먹해보기!

maketheworldwise·2023년 1월 5일


이 글의 목적?

프로젝트는 생성했으니 JPA를 찍먹해보고자 한다. 가볍게 정리해보자. ⭐️

JPA를 사용하기 위해 필요한 객체

JPA를 사용하기 위해 필요한 객체는 총 3가지다.

  • EntityManagerFactory
  • EntityManager
  • EntityTransaction

EntityManagerFactory

말 그래도 EntityManager를 찍어내는 공장이다. 중요한 점은 EntityManagerFactory의 경우 웹 서버가 올라오는 시점에 DB당 하나씩만 생성된다는 것이다.

EntityManagerFactory는 이전 글에서 구성한 JPA 설정 정보를 조회해서 생성을 한다. 참고로 JPA 설정 파일에 명시한 persistence-name 값을 이용하여 생성해야한다.

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("mysql");
entityManagerFactory.close();

EntityManager

EntityManagerEntityManagerFactory 클래스가 만들어주는 객체로, DB 연결을 얻어서 쿼리를 날리고 종료되는 일을 할 때마다 반드시 만들어줘야 한다. 단, EntityManagerFactory와는 다르게 요청이 올 때마다 사용하고 버리는 것이 중요하다. (내부적으로 데이터베이스 커넥션을 물고 동작하기 때문에 사용 후 반드시 버려줘야한다!) 따라서 쓰레드간에 공유해서는 안된다는 특징이 있다.

EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.close();

EntityTransaction

JPA에서는 트랜잭션 단위가 중요하다. 즉, 반드시 트랜잭션안에서 동작해야한다는 의미다. 그 때 사용하는 객체가 EntityTransaction이다.

EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
entityTransaction.commit();

try-catch 묶어주기

예를 들어 데이터를 삽입한다고 했을 때, 커밋을 하기 전에 오류가 생길 경우 생성한 EntityManagerFactory, EntityManager는 닫을 수 없다. 문제가 되는 이유는 해당 객체들은 반드시 닫아줘야하기 때문이다.

본래라면 스프링에서 처리해주기 때문에 try-catch문으로 묶어줄 필요는 없긴하다. ㅎㅎ

try {
  // 작업...
  
  entityTransaction.commit();
} catch (Exception e) {
  entityTransaction.rollback();
} finally {
  entityManager.close();
}

entityManagerFactory.close();

JPQL

CRUD에 대한 로직은 넘어가고 JPQL에 대한 이야기로 넘어가보자.

결론적으로 말하자면, 좀 더 복잡한 쿼리를 사용해야할 때 사용하는 것이 JPQL이다. JPQL이 가진 재미있는 특징은 테이블을 대상으로 쿼리를 날리는 것이 아닌 객체를 대상으로 쿼리를 만드는 것이다.

즉, 객체지향형 쿼리를 작성하면 JPA가 각 DB에 맞게 번역을 해준다는 의미다.

try {
  List<Member> result = entityManager.createQuery("SELECT m from Member as m", Member.class)
    .setFirstResult(1) // Paging - 1번부터 10개 (limit, offset)
    .setMaxResults(10)
    .getResultList();

  for(Member member : result) {
    System.out.println("result: " + member.getName());
  }
  
  entityTransaction.commit();
} catch (Exception e) {
  entityTransaction.rollback();
} finally {
  entityManager.close();
}

entityManagerFactory.close();

이 글의 레퍼런스

profile
세상을 현명하게 이끌어갈 나의 성장 일기 📓

0개의 댓글