
프로젝트는 생성했으니 JPA를 찍먹해보고자 한다. 가볍게 정리해보자. ⭐️
JPA를 사용하기 위해 필요한 객체는 총 3가지다.
말 그래도 EntityManager를 찍어내는 공장이다. 중요한 점은 EntityManagerFactory의 경우 웹 서버가 올라오는 시점에 DB당 하나씩만 생성된다는 것이다.
EntityManagerFactory는 이전 글에서 구성한 JPA 설정 정보를 조회해서 생성을 한다. 참고로 JPA 설정 파일에 명시한 persistence-name 값을 이용하여 생성해야한다.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("mysql");
entityManagerFactory.close();

EntityManager는 EntityManagerFactory 클래스가 만들어주는 객체로, DB 연결을 얻어서 쿼리를 날리고 종료되는 일을 할 때마다 반드시 만들어줘야 한다. 단, EntityManagerFactory와는 다르게 요청이 올 때마다 사용하고 버리는 것이 중요하다. (내부적으로 데이터베이스 커넥션을 물고 동작하기 때문에 사용 후 반드시 버려줘야한다!) 따라서 쓰레드간에 공유해서는 안된다는 특징이 있다.
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.close();
JPA에서는 트랜잭션 단위가 중요하다. 즉, 반드시 트랜잭션안에서 동작해야한다는 의미다. 그 때 사용하는 객체가 EntityTransaction이다.
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
entityTransaction.commit();
예를 들어 데이터를 삽입한다고 했을 때, 커밋을 하기 전에 오류가 생길 경우 생성한 EntityManagerFactory, EntityManager는 닫을 수 없다. 문제가 되는 이유는 해당 객체들은 반드시 닫아줘야하기 때문이다.
본래라면 스프링에서 처리해주기 때문에 try-catch문으로 묶어줄 필요는 없긴하다. ㅎㅎ
try {
// 작업...
entityTransaction.commit();
} catch (Exception e) {
entityTransaction.rollback();
} finally {
entityManager.close();
}
entityManagerFactory.close();
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();