JPA - Java Persistence API (자바 진영의 ORM 기술 표준)
ORM
- Object-relational mapping (객체 관계 매핑)
- 객체는 객체대로 설계
- 관계형 데이터베이스는 관계형 데이터베이스대로 설계
- ORM 프레임워크가 중간에서 매핑
- 대중적인 언어에는 대부분 ORM 기술이 존재
- 객체와 관계형 데이터베이스를 매핑한다는 뜻
- ORM 프레임워크 객체와 테이블을 매핑해서 패러다임의 불일치 문제를 개발자 대신 해결
public class JpaMain {
public static void main(String[] args) {
//[엔티티 매니저 팩토리] - 생성
final EntityManagerFactory emf =
Persistence.createEntityManagerFactory("hello");
//[엔티티 매니저] - 생성
final EntityManager em = emf.createEntityManager();
//[트랜잭션] - 획득
final 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) {}
}
코드는 3부분으로 나눠진다.
- 앤티티 매니저 설정
- 트랜잭션 관리
- 비즈니스 로직
엔티티 매니저 설정부터 살펴보자.
엔티티 매니저란
JPA의 기능 대부분을 제공한다.
엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
엔티티 매니저 생성 과정은 아래와 같다.
- 엔티티 매니저 팩토리 생성
- EntityManagerFactory emf = Persistence.createEntityManagerFactory("...");
- META-INF/persistence.xml에서 persistence-unit을 찾아서 엔티티 매니저 팩토리를 생성한다.
- 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.
- 엔티티 매니저 생성
- EntityManager em = emf.createEntityManager();
- 엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다.
- 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드간에 공유하거나 재사용하면 안된다.
- 종료
- em.close() , emf.close()
- 사용이 끝난 엔티티 매니저와 애플리케이션을 종료할 때 엔티티 매니저 팩토리는 반드시 종료해준다.
- 그래야 데이터베이스 커넥션이 반환된다. (자세한 내용은 이후에 알아본다.)
트랜잭션 관리
JPA를 사용하면 트랜잭션 안에서 데이터를 변경해야 한다.
트랜잭션 없이 데이터를 변경하면 예외가 발생한다.
//[트랜잭션] - 획득
final EntityTransaction tx = em.getTransaction();
try {
tx.begin(); //[트랜잭션] - 시작
logic(em); //비즈니스 로직 실행
tx.commit(); //[트랜잭션] - 커밋
} catch (Exception e) {
tx.rollback(); //[트랜잭션] - 롤백
} finally {
em.close(); //[엔티티 매니저] - 종료
}
기본적으로 비즈니스 로직이 정상 동작하면 트랜잭션을 커밋하고 예외가 발생하면 트랜잭션을 롤백하는 코드를 작성하도록 한다.
비즈니스 로직
한 건 조회
Member member = em.find(Member.class, id);
등록
em.persist(member);
삭제
em.remove(member);
수정
Member member = em.find(Member.class, id);
member.setName("member01");
수정은 특이하게 em.update() 또는 em.persist() 같은 메소드 없이 반영된다.
JPA는 어떤 엔티티가 변경되었는지 추적하는 기능을 갖고있다. (영속성 관리에서 자세히 알아보자.)
하나 이상 조회
TypedQuery<Member> query =
em.createQuery("select m from Member m", Member.class);
List<Member> members = query.getResultList();
em.createQuery("select m from Member m", Member.class); 중에서
"select m from Member m"을 보면 SQL과 굉장히 유사하다.
이건 JPA에서 제공하는 JPQL이라고 한다.
JPQL과 SQL
JPQL은 SQL과 문법이 거의 유사해서 SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 등을 사용할 수 있다.
JQPL과 SQL의 차이는 아래와 같다.
- JPQL은 엔티티 객체를 대상으로 쿼리한다. 쉽게 말해 클래스와 필드를 대상으로 쿼리한다.
- SQL은 데이터베이스 테이블을 대상으로 쿼리한다.
사용 방법
사용방법은 아래와 같다.
- em.createQuery(JPQL, 반환 타입) 메소드를 실행한다. TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
- 쿼리 객체를 생성한 후 쿼리 객체의 getResultList() 메소드를 호출하면 된다. List<Member> members = query.getResultList();
JPA는 JPQL을 분석해서 적절한 SQL을 만들어 데이터베이스에서 데이터를 조회한다.
(자세한 내용은 객체 지향 쿼리 언어 부분에서 알아보자.)
엔티티 매니저 팩토리와 엔티티 매니저
JPA를 사용할 때 반드시 알아야하는 개념인 엔티티 매니저 팩토리와 엔티티 매니저에 대해서 알아보자.
엔티티 매니저 팩토리는 클라이언트의 요청이 왔을 때 엔티티 매니저를 생성하는 역할을 한다.
그리고 생성된 엔티티 매니저는 엔티티를 저장,수정,삭제,조회하는 등 엔티티와 관련된 일을 처리한다.
그림으로 표현하면 아래와 같다.
엔티티 매니저 팩토리
역할
엔티티 매니저를 생성한다.
코드
엔티티 매니저 팩토리 객체 생성 코드이다.
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jpabook");
이때 META-INF/persistence.xml 에 있는 정보를 바탕으로 EntityManagerFactory 를 생성한다.
엔티티 매니저
역할
엔티티 관리자로서 엔티티와 관련된 모든 일을 담당한다.
코드
엔티티 매니저 객체 생성 코드이다.
EntityManager em = emf.createEntityManager();
주의사항
엔티티 매니저는 여로 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 공유하면 안된다.
반면에, 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하다.
참고
엔티티 매니저가 DB 커넥션을 얻는 시점 : 엔티티 매니저는 DB 연결이 꼭 필요한 시점에 커넥션을 얻는다. (객체 생성 시점이 아니다.)
'Develop > JPA' 카테고리의 다른 글
[JPA/기본편] 연관관계 (1) | 2024.03.20 |
---|---|
[JPA/기본편] 엔티티 매핑 (0) | 2024.03.20 |
[JPA/기본편] 준영속 상태 (0) | 2024.03.20 |
[JPA/기본편] 플러시 (0) | 2024.03.20 |
[JPA/기본편] 영속성 컨텍스트 (0) | 2024.03.20 |
댓글