Updated:

1. 개요

EntityManagerFactory는 하나만 생성해서 애플리케이션 전체에서 공유하고, EntityManager는 쓰레드간 공유를 하면 안돼서 사용하고 바로 버려야 한다. JPA의 모든 데이터 변경은 트랜잭션 안에서 실행되는데, EntityManager는 트랜잭션마다 생성된다고 생각하면 된다.

이번에는 JPA 개발환경을 설정하고, 간단하게 CRUD하는 방법에 대해 알아보도록 하자.

2. JPA 의존성 추가

[build.gradle]

1
2
3
4
dependencies {
    implementation 'org.hibernate:hibernate-core:5.6.8.Final'
    runtimeOnly 'com.h2database:h2:2.1.212'
}

Line 2 : 하이버네이트 구현체를 사용하기 위한 의존성 추가

Line 3 : H2 Database를 사용하기 위한 의존성 추가 (다운받은 버전으로 사용)

3. JPA 설정 추가

[resource/META-INF/persistence.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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">
        <class>hellojpa.Member</class>
        <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"/>
        </properties>
    </persistence-unit>
</persistence>

Line 5 : 고유한 이름으로, 일반적으로 연결할 DB당 하나의 persistence-unit을 등록

Line 6 : 엔티티 클래스를 설정 (패키지 명 포함하여 입력)

Line 8 ~ 11 : 사용할 DB 연결정보 설정

Line 12 : 사용할 DB 방언 설정 (방언에 따라 쿼리가 다르게 수행)

Line 14 : 실행되는 쿼리를 보여주기 위한 설정

Line 15 : 쿼리를 깔끔하게 정리해서 보여주기 위한 설정

Line 16 : 쿼리에 주석을 표시하기 위한 설정

4. 객체와 테이블 매핑

4-1. 테이블 생성

1
2
3
4
5
create table member (
    id bigint not null,
    name varchar(255),
    primary key (id)
);

4-2. 엔티티 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Entity
public class Member {

    @Id
    private Long id;

    private String name;

    private Long getId() {
        return id;
    }

    private void setId(Long id) {
        this.id = id;
    }

    private String getName() {
        return name;
    }

    private void setName(String name) {
        this.name = name;
    }
}

5. CRUD

5-1. 등록

5-1-1. 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class JpaMain {
    
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Member member = new Member();
            member.setId(1L);
            member.setName("helloA");

            em.persist(member);

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

Line 4 : persistence.xml의 persistence-unit에 설정한 이름 가져와서 EntityManagerFactory 생성

Line 5 : EntityManagerFactory로부터 EntityManager 생성

Line 7 : JPA의 모든 데이터 변경은 트랜잭션 안에서 수행

Line 15 : em.persist()를 통해 Member 저장

5-1-2. 실행 결과

5-2. 조회

5-2-1. 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Member findMember = em.find(Member.class, 1L);
            System.out.println("findMember.getId() = " + findMember.getId());
            System.out.println("findMember.getName() = " + findMember.getName());

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

Line 4 : persistence.xml의 persistence-unit에 설정한 이름 가져와서 EntityManagerFactory 생성

Line 5 : EntityManagerFactory로부터 EntityManager 생성

Line 7 : JPA의 모든 데이터 변경은 트랜잭션 안에서 수행

Line 11 : em.find()를 통해 Member 테이블에 저장된 데이터 조회

5-2-2. 실행 결과

5-3. 수정

5-3-1. 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Member findMember = em.find(Member.class, 1L);
            findMember.setName("HelloJPA");

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

Line 4 : persistence.xml의 persistence-unit에 설정한 이름 가져와서 EntityManagerFactory 생성

Line 5 : EntityManagerFactory로부터 EntityManager 생성

Line 7 : JPA의 모든 데이터 변경은 트랜잭션 안에서 수행

Line 12 : em.find()를 통해 조회 후 setter를 통해 변경 (변경 감지를 통해 자동으로 테이블에 반영)

5-3-2. 실행 결과

5-4. 삭제

5-4-1. 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Member findMember = em.find(Member.class, 1L);
            em.remove(findMember);

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

Line 4 : persistence.xml의 persistence-unit에 설정한 이름 가져와서 EntityManagerFactory 생성

Line 5 : EntityManagerFactory로부터 EntityManager 생성

Line 7 : JPA의 모든 데이터 변경은 트랜잭션 안에서 수행

Line 12 : em.remove()를 통해 데이터 삭제

5-4-2. 실행 결과

출처 : 자바 ORM 표준 JPA 프로그래밍 - 기본편

Updated:

Leave a comment