JPA는 persistence.xml 파일을 통해 필요한 설정 정보를 관리한다. META-INF/persistence.xml 클래스 패스 경로에 있다면 별도의 설정 없이 JPA가 인식할 수 있다.
<persistence xmln="https://xmlns.jcp.org/xml/ns/persistence" version="2.1">
설정 파일은 위와 같이 persistence로 시작한다. 여기서 xml 네임스페이스(xmlns)와 버전을 지정한다.
<persistence-unit name="jpabook">
영속성 유닛 (persistence unit)은 일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록한다.
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
위의 4가지 속성은 JPA 표준 속성으로 JDBC 드라이버, DB 접속 아이디, DB 접속 패스워드, DB 접속 URL로 구성된다.
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
하이버네이트 속성으로, 데이터베이스 방언(SQL 표준을 지키기 않거나 특정 데이터베이스만의 고유한 기능)을 설정한다.
[옵션]으로 설정된 부분들은 하이버네이트 전용 속성으로 실행한 SQL를 출력하고 보기 쉽게 정렬, 주석도 함께 출력, 키 생성 전략을 설정해 준 것이다.
Entity Manager 생성 과정
1. Persistence가 persistence.xml을 통해 설정 정보를 조회한다.
2. Persistence가 EntityManagerFactory를 생성한다.
3. EntityManagerFactory가 EntityManager를 생성한다.
JPA를 시작하기 위해서는 persistence.xml의 설정 정보를 통해 EntityManagerFactory를 생성해야 한다. 이를 위해 Persistence 클래스를 사용한다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
앞서 말했듯이, META-INF/persistence.xml에서 이름이 jpabook인 영속성 유닛을 찾아 EntityManagerFactory를 생성하게 된다. 이 때, JPA를 동작시키키 위한 기반 객체를 생성하고, 상황에 따라서는 데이터베이스 커넥션 풀도 생성해야 하므로 EntityManagerFactory를 생성하는 비용은 매우 크다. 따라서 EntityManagerFactory는 어플리케이션 전체에서 딱 한 번만 생성하고 공유해 사용하도록 해야한다.
EntityManager em = emf.createEntityManager();
EntityManagerFactory를 이용해 EntityManager를 생성한다. JPA의 대부분의 기능은 EntityManager가 제공한다. EntityManager는 DB 커넥션과 밀접한 관계가 있기 때문에 스레드 간에 공유 및 재사용을 해서는 안된다.
// EntityManager 종료
em.close();
// EntityManagerFactory 종료
emf.close();
사용이 끝난 EntityManager는 반드시 종료해야 하고, 어플리케이션을 종료할 때도 EntityManagerFactory를 종료해야 한다.
JPA를 사용할 때는 반드시 Transaction 안에서 데이터를 변경해야 한다.
EntityTransaction tx = em.getTransaction(); //트랜잭션 기능 획득
try {
tx.begin(); //트랜잭션 시작
logic(em); //비즈니스 로직
tx.commit();//트랜잭션 커밋
}
catch (Exception e) {
e.printStackTrace();
tx.rollback(); //트랜잭션 롤백
}
finally {
em.close(); //엔티티 매니저 종료
}
emf.close(); //엔티티 매니저 팩토리 종료
Transaction을 시작하려면 EntityManager로부터 getTransaction()을 통해 트랜잭션 API를 받아와야 한다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
EntityManager em = emf.createEntityManager();
// 1. 등록
String name = "Hello";
Member member = new Member();
member.setName(name);
em.persist(member);
// 2. 수정
member.setAge(29);
// 3. 삭제
em.remove(member);
// 4. 단 건 조회
Member searchMember = em.find(Member.class, name);
어플리케이션이 필요한 데이터만 불러오기 위해서는 검색 조건이 포함된 SQL을 사용하는 수밖에 없다. 따라서 JPA는 JPQL(Java Persistence Query Language)라는 쿼리 언어로 이러한 문제를 해결한다. 이는 추후에 더 자세하게 알아보도록 하겠다.