꿈꾸는 새벽하늘

02장. JPA 시작 본문

🌿 Spring & Spring Boot/📗 자바 ORM 표준 JPA 프로그래밍

02장. JPA 시작

rovemin 2023. 5. 22. 23:51

예제 프로젝트를 공부하기 위해 먼저 IDE를 설치하고 프로젝트를 불러온 뒤, H2 데이터베이스를 설치한다.

프로젝트는 Maven > Existing Maven Projects를 통해 불러온다.

H2 데이터베이스는 JVM 메모리 안에서 실행되는 임베디드 모드와 실제 데이터베이스처럼 별도의 서버를 띄워서 동작하는 서버 모드가 있다. 지금은  H2 데이터베이스를 서버 모드로 실행한다.

1. 라이브러리와 프로젝트 구조

JPA 구현체로 하이버네이트를 사용하기 위한 핵심 라이브러리는 다음과 같다.

  • hibernate-core: 하이버네이트 라이브러리
  • hibernate-entitymanager: 하이버네이트가 JPA 구현체로 동작하도록 JPA 표준을 구현한 라이브러리
  • hibernate-jpa-2.1-api: JPA 2.1 표준 API를 모아둔 라이브러리

1) 메이븐(Maven)

  • 라이브러리를 관리하고 빌드하는 도구이다.
  • 라이브러리 관리 기능과 빌드 기능을 제공한다.

2) 메이븐 설정 파일 pom.xml

<dependencies>에 사용할 라이브러리를 지정한다.

groupId + artifactId + version을 적으면 라이브러리(jar 파일)를 메이븐 공식 저장소에서 내려받아 라이브러리에 추가해준다.

JPA 하이버네이트 구현체 사용에는 많은 라이브러리가 필요하지만 핵심 라이브러리는 아래 두 가지이다.

  • JPA, 하이버네이트(hybernate-entitymanager): hybernate-entitymanager를 라이브러리로 지정하면 hibernate-core.jar과 hibernate-jpa-2.1-api.jar도 함께 내려받게 된다.
  • H2 데이터베이스

2. 객체 매핑

JPA를 사용하려면 먼저 회원 클래스와 회원 테이블을 매핑해야 한다.

매핑 정보에 따라 매핑 어노테이션을 추가한다. (JPA 어노테이션의 패키지는 javax.persistence이다.)

JPA는 매핑 정보에 의해 어떤 엔티티를 어떤 테이블에 저장해야 하는지 알 수 있다.

@Entity

  • 이 클래스를 테이블과 매핑한다는 것을 JPA에게 알려준다.
  • @Entity가 사용된 클래스는 엔티티 클래스라 칭한다.

@Table

  • 엔티티 클래스에 매핑할 테이블 정보를 알려준다.
  • 이 어노테이션을 생략하면 클래스 이름을 테이블 이름으로 매핑한다.

@Id

  • 엔티티 클래스의 필드를 테이블의 기본 키(primary key)에 매핑한다.
  • @Id가 사용된 필드는 식별자 필드라 한다.

@Column

  • 필드를 컬럼에 매핑한다.

매핑 정보가 없는 필드

  • 매핑 어노테이션을 생략한 경우에는 필드명을 사용해서 컬럼명으로 매핑한다.

3. persistence.xml 설정

JPA는 persistence.xml을 사용해서 필요한 설정 정보를 관리한다.

 

JPA 2.1을 사용하기 위해 xmlns와 version을 명시한다.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">

 

연결할 데이터베이스당 하나의 영속성 유닛을 등록한다. 이때 영속성 유닛에는 고유한 이름을 부여해야 한다.

<persistence-unit name="jpastudy">

 

이후 아래와 같은 속성들을 추가로 설정한다.

  • JPA 표준 속성
    • javax.persistence.jdbc.driver: JDBC 드라이버
    • javax.persistence.jdbc.user: 데이터베이스 접속 아이디
    • javax.persistence.jdbc.password: 데이터베이스 접속 비밀번호
    • javax.persistence.jdbc.url: 데이터베이스 접속 URL
  • 하이버네이트 속성
    • hibernate.dialect: 데이터베이스 방언 설정

데이터베이스 방언

JPA는 특정 데이터베이스에 종속적이지 않은 기술이기 때문에 다른 데이터베이스로 손쉽게 교체할 수 있다.

그러나 각 데이터베이스가 제공하는 SQL 문법과 함수가 조금씩 달라서 문제가 생길 수 있다.

SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능을 JPA에서는 방언이라 일컫는다.

 

하이버네이트는 다양한 데이터베이스 방언을 제공한다.

  • H2: org.hibernate.dialect.H2Dialect
  • 오라클 10g: org.hibernate.dialect.Oracle10gDialect
  • MySQL: org.hibernate.dialect.MySQL5InnoDBDialect

4. 애플리케이션 개발

객체 매핑과 persistence.xml 설정을 완료하면 본격적으로 JPA 애플리케이션 개발을 시작한다.

1) 엔티티 매니저 설정

(1) 엔티티 매니저 팩토리 생성

JPA를 시작하기 위해 persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성한다.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpastudy");

엔티티 매니저 팩토리는 애플리케이션 전체에서 한 번만 생성하고 이후 공유해서 사용한다.

 

(2) 엔티티 매니저 생성

EntityManager em = emf.createEntityManager();

엔티티 매니저는 대부분의 JPA 기능을 제공한다.

대표적으로 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.

엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드 간에 공유하거나 재사용하면 안 된다는 점을 주의해야 한다.

 

(3) 종료

em.close();	// 엔티티 매니저 종료

emf.close();	// 엔티티 매니저 팩토리 종료

2) 트랜잭션 관리

JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다.

트랜잭션을 시작하려면 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.

트랜잭션 API를 사용해서 비즈니스 로직이 정상 동작하면 트랜잭션을 커밋(commit)하고 예외가 발생하면 트랜잭션을 롤백(rollback)한다.

3) 비즈니스 로직

회원 엔티티를 생성한 뒤 엔티티 매니저를 통해 데이터베이스에 등록, 수정, 삭제, 조회한다.

 

(1) 등록: 엔티티 매니저의 persist() 메소드에 저장할 엔티티를 넘겨주어 엔티티를 저장한다.

(2) 수정: 메소드를 호출하는 것이 아니라 엔티티의 값을 변경하는 방식으로 수정한다.

(3) 삭제: 엔티티 매니저의 remove() 메소드에 삭제하려는 엔티티를 넘겨주어 엔티티를 삭제한다.

(4) 조회(한 건 조회): find() 메소드를 이용하여 조회할 엔티티 타입과 @Id로 데이터베이스 테이블의 기본 키와 매핑한 식별자 값으로 엔티티 하나를 조회한다.

4) JPQL

JPA에서 제공하는 JPQL은 SQL을 추상화한 객체지향 쿼리 언어이다.

JPQL은 엔티티 객체, 즉 클래스와 필드를 대상으로 쿼리한다. 반면, SQL은 데이터베이스 테이블을 대상으로 쿼리한다.

JPQL을 사용하려면 em.createQuery(JPQL, 반환 타입) 메소드를 실행해서 쿼리 객체를 생성한 후 쿼리 객체의 getResultList() 메소드를 호출한다.