개발/JPA

JPA

냥덕_ 2024. 11. 22. 13:26

JPA란?

JPA는 Java Persistence API의 약자로, 자바 진영의 ORM(Object Relational Mapping) 기술 표준입니다. 간단히 말해, 애플리케이션의 객체와 데이터베이스 사이에서 매핑 작업을 담당하여 개발자가 보다 객체지향적으로 데이터를 다룰 수 있도록 돕는 기술이다.

ORM이란?

Object Relational Mapping은 객체와 관계형 데이터베이스를 매핑하며 패러다임 불일치를 해결해주는 기술

패러다임 불일치란?
객체지향 프로그래밍은 상속, 다형성, 캡슐화 같은 개념에 중점을 두지만, 관계형 데이터베이스는 데이터 중심적이며 이러한 개념이 존재하지 않는다. 객체지향적인 부분과 데이터 중심에서의 차이를 '패러다임 불일치'라고 한다. 

 

JPA는 자바 진영의 ORM API 표준 명세서다. 다시 말해 인터페이스의 집합이기 때문에 이를 구현해놓은 프레임워크들이 존재한다. 하이버네이트, 이클립스링크 등이 존재 

JPA를 사용하면 아래와 같은 장점들이 존재한다.

 

  • 생산성 향상
    • JPA는 반복적으로 작성해야 하는 CRUD SQL을 자동 생성
    • SQL을 직접 작성하지 않아도 객체 지향 코드로 데이터베이스 작업이 가능
  • 유지보수 용이
    • 데이터베이스의 스키마가 변경되더라도 관련된 모든 SQL을 직접 수정할 필요가 없음
    • 엔티티 클래스의 필드만 변경하면 JPA가 이를 기반으로 변경 사항을 자동으로 반영
  • 벤더 독립성
    • 특정 데이터베이스에 종속되지 않으며, 데이터베이스를 변경하더라도 비교적 쉽게 대응 가능
  • 객체 지향적 설계 가능
    • 상속, 연관관계 매핑, 다형성 등 객체 지향의 특성을 데이터베이스 설계에 녹여낼 수 있습니다

JPA 주요 객체

클래스 설명
Persistence JPA를 시작할 때 가장 먼저 사용되는 객체
지정된 persistence.xml의 <persistence-unit> 이름을 기반으로 EntityManagerFactory를 생성
EntityManagerFactory persistence.xml의 설정을 기반으로 DB 커넥션 풀 생성, Dialect 설정, 캐시 초기화 등 JPA 초기화 작업을 수행
EntityManager를 생성하는 팩토리 역할
EntityManager JPA의 핵심 클래스. 데이터베이스와의 상호작용을 직접 담당하며, 엔티티의 CRUD 작업을 수행
각 트랜잭션마다 새로 생성되어야 하며, 스레드 간 공유가 금지
EntityTransaction JPA에서 트랜잭션을 관리하는 객체. 데이터의 일관성을 유지하기 위해 사용
Query JPQL 또는 네이티브 SQL을 실행하기 위한 객체.
엔티티를 조회하거나 업데이트할 때 사용

대강 아래 그림 같은 구조라고 볼 수 있다.


간단 실습

1. 프로젝트 생성

프로젝트는 스프링으로 만드셔도 상관없고 그냥 일반 Java 프로젝트로 만드셔도 상관없습니다. 저는 Maven 기반 일반 자바 프로젝트롤 진행하겠습니다. 참고로 저는 Hibernate로 진행하겠습니다

Maven 

<?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>org.tkdgus</groupId>
    <artifactId>jpatest</artifactId>
    <version>1.0-SNAPSHOT</version>

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

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.6.15.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.3.0</version>
        </dependency>


    </dependencies>

</project>

 

2. DB 및 Persistence.xml 설정

DB는 docker mysql 사용하고 아래 Member 테이블을 생성해놨습니다

(docker 설치 및 mysql 컨테이너 생성은 구글링 plz...)

create table member(
    ID   bigint  not null primary key,
    name varchar(30) null,
    age  int         null
);

 

JPA 설정 파일은 /resource/META-INF/persistence.xml 경로에 존재해야 JPA가 읽어올 수 있습니다! 해당 xml 파일 기반으로 DB 설정이나 ORM 프레임워크 설정이 가능합니다
해당 파일은 JPA가 데이터베이스와 통신하는 데 필요한 정보를 담고 있습니다.

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-unit name="jpatest">
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa_demo"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="1234"/>

            <!-- DB Dialect 설정 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>

            <!-- 옵션 -->
            <!-- SQL show -->
            <property name="hibernate.show_sql" value="true"/>

            <!-- SQL 정렬 -->
            <property name="hibernate.format_sql" value="true"/>

            <!-- SQL에 관한 주석 처리 -->
            <property name="hibernate.use_sql_comments" value="true"/>

            <!-- application 실행 시 ddl 전략 -->
            <property name="hibernate.hbm2ddl.auto" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

 

hibernate 설정은 뒤에서 다시 설명하겠습니다 jdbc 설정만 저런식으로 했다 정도 이해하시면 될거 같습니다.

아래는 실제 사용 코드 예시입니다. 위에서 xml에서 지정한 unit 이름으로 EntityManagerFactory를 생성하고 EntityManager 객체를 생성한 다음 트랜잭션을 획득하는 코드 입니다 

public class Main {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatest");
        EntityManagerFactory emf2 = Persistence.createEntityManagerFactory("jpatest");

        System.out.println(emf == emf2); //false

        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();
            ...
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            em.close();
        }
    }
}