본문 바로가기
JPA/JPA

JPA 사용하기 (feat. Maven)

by 걸어가는 신사 2021. 12. 28.
스프링 부트 없이 JPA를 설정하는 방법입니다.

1. 프로젝트 생성

(1) Maven project 생성

  • JAVA 11 사용
  • Maven 선택
    • groupId: jpa-basic
    • artifactId: ex1-hello-jpa
    • version: 1.00

(2) 라이브러리 추가 - pom.xml

    <dependencies>
        <!-- JPA 하이버네이트 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.13.Final</version>
        </dependency>
        <!-- H2 데이터베이스 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.199</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>
  • hibernate 5.3.13 버전 사용
    • JPA 표준과 하이버네이트를 포함하는 라이브러리
    • hibernate-entitymanager를 라이브러리로 지정하면
      • hibernate-core.jar
      • hibernate-jpa-2.1-api.jar 라이브러리도 함께 내려받는다.
  • 데이터베이스는 h2 1.4.199 버전 사용
    • 자신이 사용한 h2 데이터베이스 버전에 맞춰줘야 한다.
  • 자바 11을 사용하는 경우 java.xml.bind를 추가해주어야 한다.
자바 11부터는 해당 라이브러리가 자바 기본에서 빠져있어 이와 같은 에러 발생 가능.
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

 

2. JPA 설정하기

(1) persistence.xml

  • JPA 설정 파일
  • 파일 위치
  • src/main
    • java
    • resources
      • META_INF
        • persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <persistence-unit name="hello">
        <properties>
            <!-- 필수 속성 -->
            <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"/>
            <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="create" />-->
        </properties>
    </persistence-unit>
</persistence>
  • pom.xml에 설정하였던 persistence-unit name 이름을 지정한다.
    • 일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록한다.
  • javax.persistence.jdbc.driver : JDBC 드라이버
  • javax.persistence.jdbc.user : 데이터베이스 접속 아이디
  • javax.persistence.jdbc.password : 데이터베이스 접속 비밀번호
  • javax.persistence.jdbc.url : 데이터베이스 접속 URL
  • hibernate.show_sql : 하이버네이트가 실행한 SQL을 출력한다.
  • hibernate.format_sql : 하이버네이트가 실행한 SQL을 출력할 때 보기 쉽게 정렬한다.
  • hibernate.use_sql_comments : 쿼리를 출력할 때 주석도 함께 출력한다.

(2) 데이터베이스 방언

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

 

3. JPA 구동 방식

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;

public class JpaMain {
    public static void main(String[] args) {
        //Database 하나당 묶여서 돌아간다.
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        //고객이 요청이 올때마다 생성
        EntityManager em = emf.createEntityManager();
        //JPA data 모든 변경은 transaction 안에서 일어나야 한다.
        EntityTransaction tx = em.getTransaction();
        tx.begin();

		...
        tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}

 

(1) EntityMangerFactory 생성

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

(2) EntityManger 생성

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

(3) 종료

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

(4) EntityTransaction 관리

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

 

4. JPA를 이용한 CRUD

  • 등록, 수정, 삭제, 조회 작업은 엔티티 매니저를 통해서 수행된다.
//객체 생성
Member member = new Member();
member.setName("helloA");

//Create
em.persist(member);

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

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

//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());
}

(1) Create

em.persist(member);
  • 엔티티를 저장하려면 엔티티 매니저의 persist() 메서드에 저장할 엔티티를 넘겨주면 된다.

(2) 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) 제공

* SQL vs JPQL

  • SQL은 데이터베이스 테이블을 대상으로 쿼리한다.
  • JPQL은 엔티티 객체를 대상으로 쿼리한다.
    • from Member는 회원 엔티티 객체를 뜻한다. JPQL은 데이터베이스 테이블을 전혀 알지 못한다.

(3) Update

updateMember.setName("helloJPA");
  • 단순히 엔티티의 값만 변경하면 JPA가 어떤 엔티티가 변경되었는지 추적하여서 UPDATE SQL을 생성하고 실행된다.

(4) Delete

em.remove(deleteMember);
  • DELETE SQL을 생성해서 실행된다.
반응형

'JPA > JPA' 카테고리의 다른 글

[JPA] 상속 관계 매핑  (0) 2022.01.03
[JPA] 연관관계 매핑 - 2  (0) 2022.01.02
[JPA] 연관관계 매핑 - 1  (0) 2022.01.01
[JPA] 엔티티 매핑 (Entity Mapping)  (0) 2021.12.31
[JPA] 영속성 컨텍스트 (Persistence context)  (0) 2021.12.29

댓글