6-keem
Gallery
About
© Powered by 6-keem

Spring JPA (Java Persistence API)

Backend
2025년 04월 01일
7분

Spring Framework

Series bookmark
  1. Spring 개요
  2. Spring 의존성 주입
  3. Spring MVC 패턴
  4. Spring MVC Web Form
  5. Spring JPA (Java Persistence API)
  6. Spring Entity Mapping
  7. Logging with SLF4J and Logback
On this page
  • JPA란?
  • JDBC vs JPA(Hibernate) vs Spring Data JPA
  • Entity Class
  • 최소 조건
  • Java Annotations
  • Entity Manager
  • Persistence Contetxt
  • Entity Lifecycle
  • EntityManager API
  • JPA Query Language (JPQL)
  • DAO (Data Access Object)
  • Spring @Transactional

이전 포스트
Spring MVC Web Form
다음 포스트
Spring Entity Mapping
thumbnail.png
교과목 내용을 정리하기 위한 글입니다. 틀린 내용이 있을 수 있으니 참고하세요

JPA란?

Standard API for Object-to-Relational Mapping (ORM)

  • 모든 저수준(low-level) SQL 처리
  • 개발자들이 객체 모델을 사용하여 프로그래밍에 집중할 수 있도록 도움

Object-To-Relational Mapping (ORM)Object-To-Relational Mapping (ORM)

단순 명세

  • 인터페이스 집합을 정의함
  • 사용하기 위해서 구현이 필요함
  • 표준 API를 사용함으로써, 공급자의 구현에 얽매이지 않음

※ JPA는 구현이 없는 명세나 인터페이스임
※ Hibernate는 JPA의 구현체임

JDBC vs JPA(Hibernate) vs Spring Data JPA

JPAJPA

  1. JDBC: Low-Level Database Access
  2. JPA: Java Persistence API를 나타내는 기술적 명세, 관계형 데이터베이스를 위한 인터페이스로 정의됨
  3. Hibernate: JPA의 구현체
  4. Spring Data JPA: JPA를 쉽게 하용하도록 만든 모듈

JPAJPA

Entity Class

데이터베이스 테이블에 매핑되는 자바 클래스

Entity ClassEntity Class

최소 조건

  • @Entity 주석 필수
  • public 혹은 protected 기본 생성자 필수 (다른 생성자도 가질 수 있음)

Java Annotations

  • 1단계: 클래스를 데이터베이스 테이블에 매핑하기
  • 2단계: 필드를 데이터베이스 컬럼에 매핑하기

@Table

Map class to database tableMap class to database table

  • 선택사항으로 없으면 클래스 이름으로 자동 설정됨

@Column

Map fields to database columnsMap fields to database columns

  • 선택사항으로 없으면 필드 이름으로 자동 설정됨

@Id, @GeneratedValue

Primary Key

Primary KeyPrimary Key

  • 각 행을 고유하게 실벽
  • 반드시 고유한 값으로 NULL일 수 없음

ID Generation Strategies

타입설명
GenerationType.Auto특정 데이터베이스를 위한 적절한 전략을 선택
GenerationType.IDENTITY데이터베이스 ID 열을 사용하여 Primary Key 할당
GenerationType.SEQUENCE데이터베이스 시퀀스로 Primary Key 할당
GenerationType.TABLE기본 키의 고유성을 보장하기 위해 기본 데이터베이스 테이블을 사용하여 할당

Entity Manager

Entity ManagerEntity Manager

  1. EntityManagerFactory : EntityManager의 객체 제공
  2. JPA EntityManager (interface) : 특정 애플리케이션에서 데이터베이스를 접근하기 위해 사용

EntityManager API는 영속적인 엔티티 인스턴스를 생성 및 제거하고, 기본 키로 엔티티를 찾으며, 엔티티를 대상으로 쿼리를 수행하는 데 사용됩니다.

ActionJPA MethodsHibernate Methods
Create/Save new EntityentityManager.persist(...)session.save(...)
Retrieve Entity by IDentityManager.find(...)session.get(...)/load(...)
Retrieve list of EntitiesentityManager.createQuery(...)session.createQuery(...)
Save or Update EntityentityManager.merge(...)session.saveOrUpdate(...)
Delete EntityentityManager.remove(...)session.delete(...)

Persistence Contetxt

Persistence ContetxtPersistence Contetxt

  1. EntityManager 객체는 Persistence Context와 연관된다.
  2. Persistence Context는 Entity 객체들의 집합으로 데이터베이스에서 엔티티를 가져오거나 데이터베이스에 저장할 때 사용되는 1차 캐시

Entity Lifecycle

Entity LifecycleEntity Lifecycle

상태Persistence Context에 있음?설명
New / Transient❌ 아님아직 저장되지 않은 순수 객체
Persistent / Managed✅ 있음Persistence Context가 관리 중
Detached❌ 아님한 번 저장됐지만 지금은 관리되지 않음
Removed✅ 있음 (삭제 대기 상태)삭제 예약된 상태. flush/commit 시 실제 삭제

EntityManager API

CRUD (Create, Read, Update, Delete)

@Override
public void save(Student theStudent){
  entityManager.persist(theStudent);
}
Save
@Override
public Student load(){
  Student myStudent = entityManager.find(Student.class, 1);
}
Retrieve

※ EntityClass와 Primary Key 전달

복잡한 연산은 어떻게 할까?

JPA Query Language (JPQL)

  • 객체들을 조회하기 위한 Query Language
  • SQL과 비슷하지만 JPQL은 entity name과 entity fields에 기반함
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);
List<Student> students = theQuery.getResultList()
Retrieving with JPQL

※ Class 이름과 Return 타입 전달

TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=`Doe`", Student.class);
List<Student> students = theQuery.getResultList()
Retrieving Student: LastName = 'Doe'
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=`Doe` OR firstName=`Daffy`", Student.class);
List<Student> students = theQuery.getResultList()
Retrieving Students using OR predicate

※ 엔티티 이름 필드 이름에 주의가 필요함

public List<Student> findByLastName(String theLastName) {
  TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=:theData", Student.class);
  
  theQuery.setParameter("theData", theLastName);
  List<Student> students = theQuery.getResultList()
}
JPQL Named Parameter

※ Query에 변수 사용 시 parameter를 설정해주어야 함

Student myStudent = entityManager.find(Student.class, 1);
 
theStudent.setFirstName("Scooby");
 
entity.merge(theStudent);
Update
int numsRowsUpdated = entityManager.createQuery(
  "UPDATE Student SET lastName=`Tester`")
  .executeUpdate();
Update last name for all Students
Student myStudent = entityManager.find(Student.class, 1);
entity.remove(theStudent);
Delete
int numsRowsUpdated = entityManager.createQuery(
  "DELETE FROM Student WHERE lastNAme=`Smith`")
  .executeUpdate();
Delete based on a condition
int numsRowsDeleted = entityManager.createQuery(
  "DELETE FROM Student")
  .executeUpdate();
Delete All Students

DAO (Data Access Object)

  1. 데이터베이스를 규격화 함
  2. JPA Entity Manager가 필요함 (조회, 저장을 위한 기본 컴포넌트)

Data Access ObjectData Access Object

JPA Entity Manager

  • JPA Entity Manager는 데이터 소스가 필요함
  • 데이터 소스는 데이터베이스 연결 정보를 정의함
  • JPA Entity Manager를 Student DAO에 자동 주입하거나 주입할 수 있음
@Repository
@Transactional
public class StudentDao {
 
  @PersistenceContext
  private EntityManager entityManager;
 
  public Student findById(Integer id) {
    return entityManager.find(Student.class, id);
  }
 
  public List<Student> findAll() {
    // create query
    TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);
 
    // return query results
    return theQuery.getResultList();
  }
 
  public void save(Student theStudent) {
    entityManager.persist(theStudent);
  }
 
  public void update(Student theStudent) {
    entityManager.merge(theStudent);
  }
 
  public void delete(Integer id) {
    // retrieve the student
    Student theStudent = entityManager.find(Student.class, id);
 
    // delete the student
    entityManager.remove(theStudent);
  }
}

Spring @Transactional

  • 자동으로 JPA 코드에 대한 트랜잭션을 시작하고 종료함
  • 코드를 명시적으로 작성할 필요가 없음
  • 사용자 모르게 처리됨