본문 바로가기
Dev/JPA

[JPA] JPA 시작하기

by dev_jsk 2021. 7. 17.
728x90
반응형

실습을 통해 JPA를 학습해보자

개발환경

IDE : Visual Studio Code

Java : Open JDK 11

Maven : 3.8.1

Database : H2 (1.4.199)

Hello JPA 프로젝트 생성 & 설정

H2 Database 설치 & 실행

(1) http://www.h2database.com/ 접속 후 All Platforms 로 다운. (1.4.199 버전은 All Downloads 로 들어가면 있다.)

(2) 압축 해제 후 bin/h2.bat 실행

(3) 웹 화면에서 드라이버(jdbc:h2:tcp://localhost/~/test) 확인 후 연결

※ 웹 화면은 localhost:8082 또는 127.0.0.1:8082 로 접속 가능

 

H2 Database 장점

  • 웹용 쿼리툴 제공
  • 용량 작고 라이브러리 자체가 가벼움
  • MySQL, Oracle 지원
  • Sequence, Auto Increment 지원

Maven 소개 & 설치

  • 자바 라이브러리, 빌드를 관리
  • 중앙 저장소에서 자동으로 라이브러리 다운로드 및 의존성 관리
  • https://maven.apache.org/ 접속하여 3.8.1 zip 다운

Maven 프로젝트 생성

  • Group Id : jpa.basic
  • Artifact Id : ex1-hello-jpa
  • Version : 1.0.0

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

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>jpa.basic</groupId>
    <artifactId>ex1-hello-jpa</artifactId>
    <version>1.0.0</version>

    <name>ex1-hello-jpa</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- JPA 하이버네이트 -->
        <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>1.4.199</version>
        </dependency>
        <!-- JDK 11 이상 사용 시 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>

</project>

JPA 설정 (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 ~ : JPA 표준 속성 -->
            <!-- hibernate ~ : 하이버네이트 전용 속성 -->
            
            <!-- 필수 속성 -->
            <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.jdbc.batch_size" value="10" />
            <!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
        </properties>
    </persistence-unit>
</persistence>

데이터베이스 방언

  • SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능을 뜻한다.
  • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다.
    가변문자 : MySQL(VARCHAR), Oracle(VARCHAR2)
    문자열 자르는 함수 : SQL 표준(SUBSTRING()), Oracle(SUBSTR())
    페이징 : MySQL(LIMIT), Oracle(ROWNUM)

※ JPA는 특정 데이터베이스에 종속되지 않으며 하이버네이트는 40가지 이상의 데이터베이스 방언을 지원한다.

 

Hello JPA 애플리케이션 개발

JPA 구동 방식

JPA 는 다음과 같은 방식으로 동작한다.

실습 1. JpaMain 클래스 생성

java/hellojpa/JpaMain.java 생성

package hellojpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        // WebServer 구동 시점에서 DB당 1개만 생성된다.
        // createEntityManagerFactory 함수의 인수는 persistence-unit name
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // WebServer 종료 시 close
        emf.close();
    }
}

실습 2. Member 저장, 수정, 삭제, 조회

1. H2 DB에 Member 테이블 생성하기

2. Member 클래스 생성하기

java/hellojpa/Member.java 생성

package hellojpa;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity  // JPA가 관리할 객체라는 것을 의미
public class Member {

    @Id  // 데이터베이스 테이블의 PK와 매핑
    private Long id;
    private String name;

    public Member() {}

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

3. Member 저장, 수정, 삭제, 조회 구현하기

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        // WebServer 구동 시점에서 DB당 1개만 생성된다.
        // createEntityManagerFactory 함수의 인수는 persistence-unit name
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // 고객의 요청이 올때마다 생성 및 사용 후 버려야 한다. (=트랜잭션 마다 EntityManager 생성)
        // 주의할점으로 쓰레드간의 공유 X
        EntityManager em = emf.createEntityManager();
        // JPA의 모든 데이터 변경은 트랜잭션 안에서 실행
        // 단순 데이터 조회는 트랜잭션 필요 X
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            // 1. Member 저장
            Member member = new Member();
            member.setId(3L);
            member.setName("HelloC");
            em.persist(member);

            // 2. Member 조회 및 수정
            Member findMember = em.find(Member.class, 3L);
            System.out.println("findMember.id = " + findMember.getId());
            System.out.println("findMember.name = " + findMember.getName());
            // 수정 시 Member 객체 정보 변경 후 persist 호출 할 필요 없다.
            // 이유는 JPA를 통해 객체를 조회하면 transaction commit 시점에 객체가 변경되었는지 확인 하고
            // 변경 내용이 있으면 자동으로 Update 쿼리를 실행한다.
            findMember.setName("HelloJPA");

            // 3. Member 삭제
            Member findMember = em.find(Member.class, 3L);
            em.remove(findMember);

            // 트랜잭션 commit 시점에 DB에 쿼리 전송
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        // WebServer 종료 시 close
        emf.close();
    }
}

4. 동작 확인

(1) 저장

(2) 수정

(3) 삭제

JPQL

  • 가장 단순한 조회 방법
    EntityManager.find()
    객체 그래프 탐색 방식(a.getB().getC())
  • JPA가 제공하는 SQL을 추상화한 객체 지향 쿼리 언어
  • SQL과 문법 유사, SELECT / FROM / WHERE / GROUP BY / HAVING / JOIN 지원
  • 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
  • SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
package hellojpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        // WebServer 구동 시점에서 DB당 1개만 생성된다.
        // createEntityManagerFactory 함수의 인수는 persistence-unit name
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // 고객의 요청이 올때마다 생성 및 사용 후 버려야 한다. (=트랜잭션 마다 EntityManager 생성)
        // 주의할점으로 쓰레드간의 공유 X
        EntityManager em = emf.createEntityManager();

        try {
            // JPQL
            // 1. JPA가 제공하는 SQL을 추상화한 객체 지향 쿼리 언어
            // 2. 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
            // 3. SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
            List<Member> result = em.createQuery("select m from Member as m", Member.class)
                    .setFirstResult(0)  // Paging startNo
                    .setMaxResults(10)  // Paging endNo
                    .getResultList();

            for (Member member : result) {
                System.out.println("member.name = " + member.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            em.close();
        }

        // WebServer 종료 시 close
        emf.close();
    }
}
728x90
반응형

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

[JPA] 실습 - 요구사항 분석과 기본 매핑  (0) 2021.08.03
[JPA] 엔티티 매핑  (0) 2021.08.02
[JPA] 영속성 관리  (0) 2021.07.20
[JPA] JPA 소개  (0) 2021.07.13
[JPA] 강좌 소개  (0) 2021.07.13

댓글