이 글은 김영한님의 Inflearn 강의를 학습한 내용을 정리하였습니다.
글에 포함된 그림의 출처는 자바 ORM 표준 JPA 프로그래밍 - 기본편 강의와 자바 ORM 표준 JPA 프로그래밍입니다.
JPA를 학습하기 위한 객체를 테이블에서 등록/수정/삭제/조회 하는 프로젝트 생성, JPQL에 대해서 알아본다.
H2 Database
H2는 자바로 작성된 관계형 데이터베이스 관리 시스템으로
JVM 메모리 안의 임베디드 모드, 서버 띄워 동작하는 서버모드가 존재한다.H2 Database의 특징은 아래와 같다.
- 용량이 적다 (1.5M)
- 브라우저에서 쿼리 실행이 가능하다.
- MySQL, Oracle Database 시뮬레이션이 가능하다.
- Sequence, AUTO INCREMENT 기능을 지원한다.
Maven
Maven은 라이브러리 관리 기능과 빌드 기능을 제공해주는 도구이다.
프로젝트 구조는 아래와 같다.
persistence 설정은 아래와 같다.
주요 설정 부분은 아래와 같다.
2~3 줄
: JPA version과 xmlns를 명시한다. 5 줄
: 영속성 유닛을 등록한다. (name 속성은 필수이다.)7~19 줄
: 영속성 유닛에 필요한 속성을 추가한다.영속성 유닛(Persistence Unit)
일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록한다.
영속성 유닛에는 반드시 고유한 이름을 부여해야한다.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
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이란
Java Persistence Query Language의 약자로
JPA에서 제공하는 SQL을 추상화한 객체 지향 쿼리 언어이다.
JPQL은 JPA를 사용하면서 검색 조건이 포함된 SQL이 필요할 때 사용한다.
JPQL은 SQL과 문법이 거의 유사해서 SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 등을 사용할 수 있다.
JQPL과 SQL의 차이는 아래와 같다.
사용방법은 아래와 같다.
TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
List<Member> members = query.getResultList();
JPA는 JPQL을 분석해서 적절한 SQL을 만들어 데이터베이스에서 데이터를 조회한다.
(자세한 내용은 객체 지향 쿼리 언어 부분에서 알아보자.)
JPA를 사용하기 위한 개발 환경을 설정하고, JPA를 사용해서 Member 객체를 테이블에 등록/수정/삭제/조회하는 애플리케이션을 만들었다.
이 과정에서 엔티티 매니저와 트랜젝션 관리 그리고 JPQL에 대해 간단히 알아보았다.
다음 장은 JPA의 핵심 기능인 영속성 관리에 대해 알아보자.