BackEnd/JPA

[JPA] SpringBoot + JPA 시작하기

dev seon 2024. 12. 13. 15:11

 

JPA는 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스입니다.

즉, 구현을 하기 위해서는 라이브러리를 선택해야 하는 것입니다.

일반적으로 JPA에서는 Hibernate를 구현체로 선택하는 경우가 많습니다.

그러나 반드시 Hibernate를 사용할 필요는 없습니다!!

01 의존성 주입하기

스프링 프로젝트에 JPA를 적용하기 위해서는 의존성 주입이 필요합니다.

MVN Repository에서 Spring boot starter data jpa와 Mysql connector를 가져옵니다.

1. Spring Data JPA

스프링부트 버전에 맞추어 자동으로 JPA 관련 라이브러리들의 버전을 관리해주는 라이브러리입니다.

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

2. DB Driver - MySQL

여러 DB 중에 저는 MySQL을 선택했고 커넥터를 가져왔습니다.

<dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
</dependency>

02 매핑 어노테이션

자바 클래스에서 JPA를 사용하기 위해서 필요한 매핑 어노테이션을 정리해봅시다.

아래와 같이 persistence를 import 한 후 관련 어노테이션을 사용할 수 있습니다.

import javax.persistence.*;
  • @Entity : 클래스를 테이블과 매핑 → 엔티티 클래스
  • @Table : 엔티티 클래스에 매핑할 테이블 정보를 알려줌, 생략할 경우 클래스 이름을 테이블 이름으로 매핑
  • @Id : 엔티티 클래스의 필드를 테이블의 기본 키에 매핑함, 식별자 필드
  • @Column : 필드를 컬럼에 매핑. name 속성을 사용해 매핑 가능

매핑 정보가 없는 필드의 경우에는 필드명을 사용해서 컬럼명으로 매핑할 수 있습니다.

User 엔티티 클래스를 아래와 같이 예시로 정의해볼 수 있습니다.

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;

    private String name;
    private String email;

    // Getter & Setter
    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;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

03 persistence.xml

resources/META-INF/persistence.xml에 아래와 같이 설정을 정리합니다.

persistence라는 이름처럼 JPA의 가장 기본인 영속성 설정을 위해 이 파일이 필요합니다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
	<persistence-unit name="JPAPractice">
		<class>com.ms.entity.Board</class>
		
		<properties>
			<!-- 드라이버 클래스, 계정, 비밀번호, JDBC URL 정보, JPA 방언 설정 -->
			<property name ="javax.persistence.jdbc.driver" value = "com.mysql.cj.jdbc.Driver"></property>
			<property name="javax.persistence.jdbc.user"  value="ROOT"/>
			<property name="javax.persistence.jdbc.password" value="PASSWORD"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>
			<property name="hibernate.dialect" value = "org.hibernate.dialect.MySQL5Dialect"/>
			
			<!-- 콘솔 출력 여부, 콘솔 출력 포맷, 주석 출력 여부, 키 생성 전략 여부, DDL 자동 실행 여부 -->
			<property name="hibernate.show_sql" value="true"/>
			<property name="hibernate.format_sql" value="true"/> 
			<property name="hibernate.use_sql_comments" value = "false"/>
			<property name="hibernate.id.new_generator_mappings" value="true"/>
			<property name="hibernate.hbm2ddl.auto" value="update"/>
		</properties>
		
		
	</persistence-unit>
</persistence>

데이터베이스 방언

데이터베이스마다 SQL문법과 함수가 조금씩 다릅니다.

SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능이 있는 경우 이 설정을 통해 문제를 해결할 수 있습니다.

04 엔티티 매니저

엔티티 매니저는 JPA의 핵심 인터페이스로 애플리케이션에서 DB 작업을 수행합니다.

엔티티 매니저는 영속성 컨텍스트라는 캐시를 통해 엔티티를 관리하고 데이터베이스와 동기화합니다.

영속성 컨텍스트에 대해서는 다음 글에서 다루어보겠습니다.

1. 엔티티 매니저 팩토리

엔티티 매니저는 EntityManagerFactory를 통해 생성할 수 있습니다.

persistence.xml 설정 정보를 통해 엔티티 매니저 팩토리를 생성할수 있는데,

이때 비용이 아주 크므로 애플리케이션 전체에서 딱 한 번만 생성해야 합니다.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("exampleUnit");

2. 엔티티 매니저 생성

엔티티 매니저를 사용해 엔티티를 데이터베이스와 상호작용할 수 있습니다.

이때, 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드 간에 공유하거나 재사용해서는 안됩니다.

EntityManager em = emf.createEntityManager();

3. 트랜잭션 관리

데이터베이스 작업의 논리적 단위인 트랜잭션.

성공적으로 완료되면 변경사항을 데이터베이스에 저장하고

실패하면 롤백하여 데이터베이스 상태를 이전으로 되돌립니다.

em.getTransaction().begin(); //시작
em.getTransaction().commit(); //완료

4. 엔티티 CRUD

  • 저장 : em.persist(entity)
  • 조회 : em.find(EntityClass.class, primaryKey)
  • 수정 : 영속 상태 엔티티의 필드 값을 변경하면 자동으로 반영됨
  • 삭제 : em.remove(entity)

5. 종료

사용이 끝난 엔티티 매니저를 종료해 자원을 해제합니다.

애플리케이션을 종료할 때 엔티티 매니저 팩토리도 종료됩니다.

em.close();
emf.close();

전체 코드

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class JpaExample {
    public static void main(String[] args) {
        // EntityManagerFactory 생성
				EntityManagerFactory emf = Persistence.createEntityManagerFactory("exampleUnit");
        // EntityManager 생성
        EntityManager em = emf.createEntityManager();

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

        // 엔티티 생성 및 저장
        User user = new User();
        user.setId(1L);
        user.setName("John Doe");
        user.setEmail("john.doe@example.com");
        em.persist(user);

        // 트랜잭션 커밋
        em.getTransaction().commit();

        // EntityManager 및 EntityManagerFactory 종료
        em.close();
        emf.close();
    }
}