1. JPA 프로젝트 설정
Maven 과 H2 데이터베이스를 사용한다는 전제 하에 설명
먼저, pom.xml 에 JPA와 DB 사용을 위한 라이브러리 dependencies 추가
<!-- JPA hibernate 사용 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.10.Final</version>
</dependency>
<!-- h2 데이터베이스 사용-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
JPA 설정 파일 생성
위치: resources/META-INF/persistence.xml <= 반드시 META-INF 디렉토리 안에 만들어야 한다!
<persistence-unit name="hello">
<properties>
<!-- 필수 속성, 데이터베이스 접근 정보를 입력 -->
<property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="sa"/>
<property name="jakarta.persistence.jdbc.password" value=""/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- hibernate 옵션 설정 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
</properties>
</persistence-unit>
- persistence-unit name: JPA 에서 사용할 이름 지정
- jakarta.persistence.*: JPA 표준 속성으로 Hibernate 가 아닌 구현체에서도 통용적으로 사용
- hibernate.*: hibernate 전용 속성
- hibernate.dialect: H2 데이터베이스를 사용하므로 H2 방언을 사용하겠다 알려줌
여기서 dialect란?
데이터베이스의 "방언" 이라고 표현하는데, 각각의 데이터베이스에서 표준적이지 않은 고유의 SQL 문법과 함수를 말한다. 즉, 사투리와 비슷하다!
- 가변 문자: MySQL 에선 VARCHAR, Oracle 에선 VARCHAR2
- 문자열을 자르는 함수: SQL 표준 함수는 SUBSTRING(), Oracle 에선 SUBSTR()
- 페이징: MySQL은 LIMIT, Oracle은 ROWNUM <= 특히 페이징은 개발에서 많이 사용됨
따라서, JPA에게 "나는 H2 방언을 사용하여 개발해" 라고 알려주는 것이다. 그러면 JPA가 알아서 그 방언에 맞추어 번역해서 사용하게 해준다.
2. JPA 는 어떻게 동작하는가?
JPA 실습을 하기 전 간단하게 JPA의 구동 방식을 살펴보자

- JPA의 Persistence 라는 클래스에서 먼저 persistence.xml 에 설정해놓은 정보를 읽는다.
- EntityManagerFactory 라는 클래스를 생성한다.
- 어떤 비즈니스 요청이 올 때마다 공장에서 EntityManager 를 찍어내어 요청을 처리한다.
3. JPA 를 실습해보자
객체와 테이블을 생성하고 매핑
id, name 필드를 만든다고 했을 때 Member 테이블을 DB 에 생성하자
create table Member (
id bigint not null,
name varchar(255),
primary key (id)
);
테이블과 매핑시키기 위해 Member 클래스를 생성한다.
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity // jpa에서 관리 대상으로 인식, 필수
public class Member {
@Id // pk
private Long id;
private String name;
}
- @Entity: jpa가 관리할 객체로 인식할 수 있게 하는 어노테이션, jpa를 사용하기 위해선 필수
- @Id: 데이터베이스의 pk와 매핑되는 값
JPA 사용하기
import jakarta.persistence.*;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 1. EntityManagerFactory 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// 2. EntityManager 생성
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); //3. 트랜잭션 시작
try {
// EntityManager api를 사용하여 데이터 조회, 저장, 수정, 변경 등
// 여기서 고객 요청을 처리할 코드 수행..
transaction.commit(); // 4. DB 반영을 위해선 필수, 실제 쿼리가 날라가는 시점
} catch (Exception e) {
transaction.rollback(); // 5. 에러 발생 시엔 롤백
} finally {
em.close(); // 6. DB 커넥션을 물고있기 때문에 꼭 닫아서 반환
}
emf.close(); // 7. 애플리케이션이 끝나면 닫아줌
}
}
1. 애플리케이션 실행 시점에서 EntityManagerFactory 를 하나 생성하여 전체에서 공유한다.
2. 고객의 요청이 있을 때 EntityManagerFactory 에서 EntityManager 를 하나 생성한다.
3. 데이터 변경을 위해 EntityManager 로부터 트랜잭션을 하나 생성하고 시작한다.
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행한다.
- 즉, 트랜잭션을 시작하지 않으면 데이터 변경을 DB에 반영할 수 없다.
- 예외, 데이터 조회 시에는 트랜잭션이 없어도 가능하다.
4. 에러없이 코드가 정상적으로 처리되면 트랜잭션을 commit한다.
- 실제 DB에 데이터 변경이 반영되는 시점
- SQL 쿼리가 날라가는 시점
5. 에러가 발생한 경우 트랜잭션을 롤백, 즉 원래의 상태로 되돌린다.
6. 요청 처리가 끝나면 EntityManager 를 close() 하여 닫는다.
7. 애플리케이션이 끝나면 EntityManagerFactory 도 종료한다.
기본적인 EntityManager API
- 저장: em.persist(entity)
- 조회: em.find(Member.class, "membeId")
- 삭제: em.remove()
'JPA' 카테고리의 다른 글
| [JPA] em.clear() 후 엔티티의 getId() 동작에 대한 의문점 🙋♂️ (0) | 2024.02.18 |
|---|---|
| [JPA] JPA란 무엇인가? (1) | 2024.01.31 |
| [JPA] JPA의 등장 배경은? (0) | 2024.01.31 |