Seyun(Marco) 2020. 12. 13. 17:14
728x90

2. JPA 기초와 매핑

JPA의 중요한 것

  1. 객체와 관계형 DB의 매핑 과정
  2. 실제 JPA는 어떻게 동작하는지

H2 데이터베이스

  • 최고의 실습용 DB
  • 가볍다 (1.5M)
  • 웹용 쿼리툴 제공
  • MySQL, Oracle DB 시뮬레이션 기능
  • 시퀀스, AUTO INCREMENT 기능 지원

Gradle

  • 자바 라이브러리, 빌드 관리
  • 라이브러리 자동 다운로드 및 의존성 관리

의존성 추가

implementation 'org.hibernate:hibernate-entitymanager:5.3.7.Final'
runtime 'com.h2database:h2:1.4.197'
  • hibernate 5.3.7.Final → JPA 2.2

객체 매핑하기

  • @Entity : JPA가 관리할 객체
  • @Id : DB PK와 매핑 할 필드
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Member {

    @Id
    private Long id;

    private String 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;
    }
}
CREATE TABLE MEMBER
(
    id   bigint not null,
    name varchar(255),
    MEMBER primary key(id)
)

persistence.xml

  • JPA 설정 파일
  • /META-INF/persistence.xml에 위치
  • javax.persistence로 시작 : JPA 표준 속성
  • hibernate로 시작 : 하이버네이트 전용 속성
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.2">

    <persistence-unit name="hello">
        <class>com.tacademy.jpaex.entity.Member</class> <!-- gradle에서만 추가 -->

        <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.user_sql_comments" value="true"/>

            <!-- <property name="hibernate.hbm2ddl.auto" value="create"/>-->
        </properties>
    </persistence-unit>
</persistence>

데이터 베이스 방언

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

tacademy-jpa-basic-2-1

  • 방언이 다르기 때문에 DB를 변경하는 작업이 쉽지가 않다. 그러나 JPA는 모든 방언에 맞춰서 다르게 쿼리를 만들어주기 때문에 쉽게 DB를 변경할 수 있다.
  • hibernate.dialect 속성에 지정
    • H2, Oracle 10g, MySQL ...
  • 하이버네이트는 45가지 방언 지원

애플리케이션 개발

엔티티 매니저 설정

tacademy-jpa-basic-2-2

  • EntityManageFactory는 애플리케이션 실행 중 한번만 실행이 되고, 사용할때마다 EntityManager가 처리하게 된다.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import com.tacademy.jpaex.entity.Member;

public class JpaExApplication {
    public static void main(String[] args) {
        // persistence.xml에 있는 설정을 가져오는 것
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();

        transaction.begin(); // 트랜잭션 시작

        try {
            Member member = new Member();
            member.setId(100L);
            member.setName("안녕하세요.");

            em.persist(member); // 저장
            transaction.commit(); // 트랜잭션 커밋
        } catch (Exception e) {
            System.out.println(e.getMessage());
            transaction.rollback();
        } finally {
            em.close(); // entitiyManager 사용 완료 후 종료
        }

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

주의

  • 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유
  • 엔티티 매니저는 쓰레드간에 공유하면 안된다.(사용하고 버려야한다.)
    • 데이터베이스 커넥션 상 묶여버리는데, 공유하게 되면 다른 커넥션이 문제가 될 수도 있다
    • 그러나 Spring을 사용하면 알아서 관리 해주기 때문에 크게 문제가 되지 않는다.
  • JPA의 모든 데이터 변경은 트랜잭션에서 처리해야한다.

출처

[토크ON세미나] JPA 프로그래밍 기본기 다지기 2강 - JPA 기초와 매핑 | T아카데미

728x90
728x90