JPA 설정하기

023·2024년 8월 6일
0

java persistence api

목록 보기
2/5
post-thumbnail

서론

이 글에서는 JPA 설정에 대해 설명한다.

1. 프로젝트 세팅

Maven pom.xml에 hibernate-entity, database driver 추가

<!-- JPA 하이버네이트 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.4.2.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.3.230</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
  • hibernate 6.4.2.Final 버전 사용하고 JPA 표준과 하이버네이트를 포함하는 라이브러리를 추가함으로써 종속성 라이브러리도 함께 내려받는다.

  • 데이터베이스는 자신이 사용한 데이터베이스 버전에 맞춰줘야 한다. 필자는 h2 데이터베이스의 2.3.230 버전이므로 maven에서도 일치시켰다.

  • 자바 11을 사용하는 경우 java.xml.bind를 추가해주어야 한다.
    자바 11부터는 해당 라이브러리가 자바 기본에서 빠져있어 이와 같은 에러 발생 가능.

Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

2. JPA 설정하기

JPA 설정 파일

  • 파일 위치 : src/main/java/resources/META_INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- JPA 버전 : 2.2 -->
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- JPA 이름 : hello -->
<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"/>

            <!-- 옵션 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments"  value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>

</persistence>
  • persistence version은 JPA의 버전을 의미한다.
  • pom.xml에 설정하였던 persistence-unit name 이름을 지정한다. 일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록한다.
  • jakarta.persistence.jdbc.driver : JDBC 드라이버를 의미한다.
  • jakarta.persistence.jdbc.user : 데이터베이스 접속 아이디를 의미한다.
  • jakarta.persistence.jdbc.password : 데이터베이스 접속 비밀번호를 의미한다.
  • jakarta.persistence.jdbc.url : 데이터베이스 접속 URL을 의미한다.
  • hibernate.show_sql : 하이버네이트가 실행한 SQL을 출력한다.
  • hibernate.format_sql : 하이버네이트가 실행한 SQL을 출력할 때 보기 쉽게 정렬한다.
  • hibernate.use_sql_comments : 쿼리를 출력할 때 주석도 함께 출력한다.
  • hibernate.hbm2ddl.auto : 애플리케이션 실행 시 데이터베이스 스키마를 자동으로 생성하거나 업데이트하는 방법을 지정한다.

데이터베이스 방언

  • JPA는 특정 데이터베이스에 종속되지 않는다.
  • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다.
  • 방언 : SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
  • 하이버네이트는 40가지 이상의 데이터베이스 방언을 지원한다.
<!-- H2 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- Oracle -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<!-- MySQL -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>

3. JPA 구동 방식

package hellojpa;

import jakarta.persistence.*;
public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");

        EntityManager entityManager = entityManagerFactory.createEntityManager();

        EntityTransaction entityTransaction = entityManager.getTransaction();
        entityTransaction.begin();

        try {
            Member member = new Member();
            member.setId(1L);
            member.setName("A");
            entityManager.persist(member);
            entityTransaction.commit();
        } catch (Exception e) {
            entityTransaction.rollback();
        } finally {
            entityManager.close();
        }
        entityManagerFactory.close();
    }
}
  • EntityMangerFactory 생성

    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
    • JPA를 시작하려면 우선 persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성해야 한다.
    • META-INF/persistence.xml에서 이름이 jpabook인 영속성 유닛(persistence-unit)을 찾아서 엔티티 매니저 팩토리를 생성한다.
    • 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.
  • EntityManger 생성

    EntityManager entityManager = emf.createEntityManager();
    • JPA의 기능 대부분은 엔티티 매니저가 제공한다.
    • 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
    • 엔티티 매니저는 내부에 데이터베이스 커넥션을 유지하면서 데이터베이스와 통신한다.
    • 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 쓰레드 간에 공유하거나 재사용하면 안 된다.
  • EntityTransaction 관리

    EntityTransaction tx = em.getTransaction();
    tx.begin();
    tx.commit();
    • JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다.
    • 트랜잭션 없이 데이터를 변경하면 예외가 발생한다.
    • 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.
  • 종료

    em.close();
    emf.close();
    • 사용이 끝난 엔티티 매니저는 반드시 종료해야 한다.
    • 애플리케이션을 종료할 때 엔티티 매니저 팩토리도 종료해야 한다.

4. JPA를 이용한 CRUD

등록, 수정, 삭제, 조회 작업은 엔티티 매니저를 통해서 수행된다.

//객체 생성
Member member = new Member();
member.setId(1L);
member.setName("A");

//Create
em.persist(member);

//한 건 조회, Read
Member findMember = em.find(Member.class, 1L);
System.out.println(findMember.getId()); // 1
System.out.println(findMember.getName()); // "A"

//Update
Member updateMember = em.find(Member.class, 1L);
updateMember.setName("B");

//Delete
Member deleteMember = em.find(Member.class, 1L);
em.remove(deleteMember);

//목록 조회, Read (JPQL)
List<Member> result = em.createQuery("select m from Member as m", Member.class).getResultList();
for (Member mem : result) {
System.out.println("member.getName() = " + mem.getName());
}
  • Create
    em.persist(member);
    • 엔티티를 저장하려면 엔티티 매니저의 persist() 메서드에 저장할 엔티티를 넘겨주면 된다.
  • Read
    //1개 조회
    Member findMember = em.find(Member.class, 1L);
    //목록 조회 (JPQL)
    List<Member> result = em.createQuery("select m from Member as m", Member.class) .getResultList();
    • find()를 이용하면 SELECT SQL을 생성하고 실행할 수 있다.
    • 필요한 데이터만 데이터베이스에서 불러오려면 결구 검색 조건이 포함된 SQL을 사용해야 한다. 이런 경우JPA에서 제공하는 JPQL(Java Persistence Query Language)를 사용한다.
  • Update
    updateMember.setName("helloJPA");
    • 단순히 엔티티의 값만 변경하면 JPA가 어떤 엔티티가 변경되었는지 추적하여서 UPDATE SQL을 생성하고 실행된다.
  • Delete
    em.remove(deleteMember);
    • DELETE SQL이 생성하고 실행된다.
  • SQL vs JPQL
    • SQL은 데이터베이스 테이블을 대상으로 쿼리한다.
    • JPQL은 엔티티 객체를 대상으로 쿼리한다.
    • from Member는 회원 엔티티 객체를 뜻한다. JPQL은 데이터베이스 테이블을 전혀 알지 못한다.
profile
Get your hands dirty

0개의 댓글