JPA 구동 방식
JPA는 자바 애플리케이션과 JDBC API 사이에서 동작된다.
동작원리를 크게보면 다음과 같다.
- 개발자가 JPA에게 명령한다.
- JPA가 JDBC API 사용해서 SQL 호출
- 결과를 받아서 동작
🧐 여기서 JPA가 어떻게 구동되는지 좀 더 자세히 알아보자.
1. Persistence 클래스에서 META-INF/persistence.xml에서 설정 정보를 읽는다.
2. EntityManagerFactory를 만든다.
- JPA를 동작시키기 위한 기반 객체이기도 하고, JPA 구현체에 따라서 DB 커넥션 풀도 생성하므로 비용이 아주 크다.
- 따라서 EntityManagerFactory는 애플리케이션 전체에서 1번만 생성하고 공유해서 사용해야 한다.
3. EntityManager를 필요할때마다 생성하여 JPA를 동작한다
- JPA의 기능 대부분 EntityManager가 제공한다.
- EntityManager를 사용해서 엔티티를 DB에 CRUD 할 수 있다.
- DB 커넥션을 유지하면서 DB와 통신할 정도로 밀접한 관계가 있으므로 쓰레드 간에 공유 또는 재사용하면 안된다.
😠 JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야한다!!!
트랜잭션 없이 데이터를 변경하면 예외가 발생한다!!!
EntityManager에서 트랜잭션 API를 받아서 사용한다.
변경 다하고 끝에 커밋(Commit)을 하고 예외는 롤백(Rollback)한다.
📝 예시를 만들어서 확인해보자.
위 코드를 주석에도 적었지만 간단하게 차례대로 적어보자면
- EntityManagerFactory 생성
- EntityManager 생성
- 트랜잭션 획득
- 비즈니스 로직 실행
- 트랜잭션 커밋
- 예외 발생했을 시 롤백 실행
- 비즈니스로직을 정상 실행 또는 예외가 발생해도 무조건 EntityManager 종료
- EntityManagerFactory 종료
이런 식으로 진행된다.
비즈니스 로직에 find() 메서드는 조회할 엔티티 타입과 @Id로 DB 테이블의 기본키와 매핑한 식별자 값으로 엔티티 하나를 조회하는 조회 메서드이다.
🧐 그렇다면 하나 이상 조회하려면 어떻게 해야하나?
JPA에서는 JPQL(Java Persistence Query Language)이라는 쿼리 언어로 해결할 수 있다.
SQL을 추상화환 JPQL이라는 객체지향 쿼리 언어이다.
SQL과 유사한 문법을 사용하지만 차이점이 있다.
- JPQL : 엔티티 객체 대상으로 쿼리한다. 즉, 클래스와 필드를 대상으로 쿼리한다. (JPQL은 DB 테이블 전혀 알지못함)
- SQL : DB 테이블을 대상으로 쿼리한다.
참고로 JPQL은 대소문자 명확하게 구분하지만, SQL은 관례상 대소문자 구분하지 않고 사용하는 경우가 많음.
될 수 있으면 SQL은 대문자만 사용하자.
JPQL 사용방법
EntityManager.createQuery(JPQL, 반환타입) 메서드를 실행한다.
쿼리 객체 생성 후 쿼리 객체의 getResultList() 메서드를 사용한다.
이런 식으로 Member를 전부 조회해서 List로 가져온 다음 for문으로 member를 전부 출력했다.
자바 ORM 표준 JPA 프로그래밍 / 김영한 지음 / 에이콘출판주식회사 출판