Home [SpringBoot] Spring Data JPA와 JPA Repository
Post
Cancel

[SpringBoot] Spring Data JPA와 JPA Repository

1월 1주차 스터디 발표 자료
개인 프로젝트를 진행하면서 도메인 설계 전에 Spring Data JPA에 대해 정리하고자 합니다!!😁
이미지 사용 출처 : https://youtu.be/OiAYmtq4Av8/

기초 개념


1. ORM(Object Relational Mapping)

객체가 테이블이 되도록 매핑시켜주는 프레임워크로, 프로그램의 복잡도를 줄이고 객체와 쿼리를 분리할 수 있다.
트랜잭션 처리나 기타 데이터베이스 관련 작업들을 좀 더 편리하게 처리할 수 있는 프레임워크이다.
ORM은 객체와 DB의 데이터를 자동으로 매핑해주기 때문에 직접 SQL문을 작성하지 않는다.
대표적 예시: JPA,Hibernate [Persistent API]

2. JPA(Java Persistent API)

JPA는 ORM과 관련된 인터페이스가 모아져있는 라이브러리, Java 진영의 표준 ORM이다.
한마디로 ORM은 큰 개념이고 JPA는 ORM을 구체화한 구현체이다.

  1. Hibernate
    ORM 프레임워크 중 하나이다.
    ➔ JPA의 실제 구현체 중 하나이며, 현재 JPA 구현체 중 가장 많이 사용된다.
    • jpa의 구현체 jpa 구현체
  2. Spring Data JPA
    Spring 프레임워크에서 JPA를 편리하게 사용할 수 있게 지원하는 라이브러리
    • CRUD 처리용 인터페이스 제공
    • Repository 개발 시 인터페이스만 작성하면 구현 객체를 동적으로 생성해서 주입
    • EntityManager를 자동으로 Bean으로 등록되기때문에, 직접 사용하지는 않는다.

➔ Hibernate에서 자주 사용되는 기능을 조금 더 쉽게 사용할 수 있게 구현해놓은 라이브러리

✔️ EntityManager?
데이터베이스에 엑세스하기 위해 사용되는 객체이며, EntityManager를 통해 데이터베이스에 데이터를 조회,등록,수정,삭제 작업을 수행한다.

jpa와 hibernate ➔ 기존 JPA를 사용하려면 EntityManager를 주입받아 사용해야하지만, SpringDataJPA는 JPA를 한단계 더 추상화 시킨 Repository 인터페이스를 제공한다. 해당 구현체는 스프링이 자동으로 생성해준다.

  • jpaRepository는 Spring Data JPA에서 제공하는 JPA 구현을 위한 인터페이스로, 간단한 상속만으로 사전에 정의된 메서드를 활용하여 DB에 create/read/update/delete 쿼리를 수행한다. JPA와 springDataJPA JPA와 레포지토리 상속

2-1.jpaRepository

jpaRepository 인터페이스에 들어가보면, Spring Data JPA에서 사용하는 메서드가 정의되어있다. JPA와 레포지토리

  • jpaRepository는 SimpleJpaRepository 클래스에서 구현되어있다. 레포지토리구현체
  • jpaRepository는 내부적으로 EntityManager가 대상 Entity의 데이터를 관리하고있기 때문에, 별도의 EntityManager의 구현이 필요없다. entityManager jpa레포지토리의 em

3. Entity 생명주기

JPA를 이해하려면, Entity 생명주기를 이해하는 건 필수인 것 같아요.📖
Entity 생명주기에 관하여 정말 잘 정리되어있는 블로그를 발견하여 출처 남기고 정리해봅니다!
이미지 사용 출처 : https://siyoon210.tistory.com/138

3-1. 영속성 컨텍스트 (Persistence Context)

  • 영속성 컨텍스트에서는 엔티티를 관리하며, EntityManager를 통해 DB의 데이터를 저장,조회,수정,삭제할 수 있다.
  • 인스턴스로 존재하는 엔티티를 관리하고 영구 저장하는 논리적 영역이다.
  • ⭐ 영속성 컨텍스트에서 관리하는 엔티티라고 해서 반드시 DB에 저장되는 것은 아니다.

✔️ 영속성?
데이터를 생성한 프로그램이 종료되어도 사라지지 않는 데이터의 특성. 즉, DB에 저장된 데이터이다.

3-2. 영속성 컨텍스트의 구조

영속성컨텍스트구조

  1. 1차 캐시 저장소
    영속성 컨텍스트가 관리하는 엔티티 정보가 담겨있으며, 해당 저장소에 저장된 상태를 영속상태라고 한다.
    영속 상태는 아직 DB에 저장되지 않은 상태이며, 단지 관리(managed)하는 상태이다.
  2. 쿼리문 저장소
    JPA는 필요한 쿼리문을 해당 저장소에 보관한다. 보관의 이유는 DB에 접근하는 횟수를 최소하여 성능향상을 이끌어낼 수 있다.
    저장해둔 쿼리문으로 DB에 접근하는 행위는 EntityManager의 flush() 함수를 사용하면 된다.

3-3. Entity 생명주기

  1. 비영속상태(new,transient)
    • 엔티티가 영속성 컨텍스트와 전혀 관련이 없는 상태
    • 객체를 생성만 한 상태
      1
      2
      3
      4
      
      // 객체를 생성한 상태 (비영속)
      Member member = new Member();
      member.setId("Member1");
      member.setUsername("회원1");
      

      비영속상태

  2. 영속상태(managed)
    • 엔티티가 영속성 컨텍스트에서 관리되고 있는 상태이다. 단, DB에 저장된 상태는 아니다.
    • EntityManager의 persist()함수를 통해 엔티티를 영속상태로 만들 수 있다.
1
2
3
4
5
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();

// 객체를 저장한 상태 (영속)
entityManager.persist(member);

영속상태 ➔ 엔티티를 저장하는 Insert 쿼리문이 생성되었으나, DB에 전달되지 않고 쿼리문 저장소에 보관된다.
즉, flush()가 실행되기 전에는 DB에 접근하지않는다. 영속상태 ➔ 엔티티를 저장하는 Insert 쿼리문이 생성되었으나, DB에 전달되지 않고 쿼리문 저장소에 보관된다.
즉, flush()가 실행되기 전에는 DB에 접근하지않는다. 여러개의엔티티 ➔ 여러개의 엔티티를 persist()하면, 해당하는 insert 쿼리문은 계속 쌓인다. flush ➔ 쌓인 쿼리문들은 flush()를 실행했을 때 DB에 반영된다. flush 이후에 entity는 사라지지않고 계속 관리된다.
➔ flush는 영속성 컨텍스트와 DB를 동기화하는 것 find ➔ EntityManager가 DB에서 find()를 통해 조회한 데이터도 영속 상태인 엔티티가 된다.
➔ 조회한 데이터는 먼저 1차 캐시 저장소에 저장되고, 그 후 저장된 엔티티 정보를 반환한다.

같은 엔티티를 한번 더 조회할 경우?
1차 캐시 저장소에 저장된 엔티티를 한번 더 조회할 경우에는 저장소에 있는 엔티티를 반환하고 실제 DB에는 접근하지 않는다! 동일한 엔티티이기 때문에, 인스턴스의 참조값도 동일하다.

3. 준영속상태(detached)

  • 영속성 컨텍스트에서 관리하던 엔티티가 관리되지 않는 상태가되면 해당 엔티티를 준영속 상태라한다.
  • 준영속 상태를 만드는 3가지 방법
    1. detach()사용
      특정 엔티티를 준영속 상태로 만든다.
      1
      
        entityManager.detach(member);
      

      detach

    2. clear()사용
      영속성 컨텍스트 전체를 초기화한다. 저장해둔 쿼리문도 동시에 초기화가 된다.
      1
      
        entityManager.clear();
      

      detach

    3. close()사용
      영속성 컨텍스트를 닫는다. 관리되던 엔티티들은 모두 준영속 상태가된다.
      1
      
        entityManager.close();
      

      detach

    4. remove()사용
      삭제된 엔티티는 영속성 컨텍스트에서 관리하지 않게되며, 해당 엔티티를 DB에서 삭제하는 DELETE 쿼리문을 보관한다.
      단, flush가 호출되기 전에는 실제 DB에 접근되지않는다.
      1
      
        entityManager.remove(member);
      

      detach

3-4. 변경감지

  • update와 관련된 EntityManager의 메소드는 정의되어 있지않다. 단지, 변경을 감지할 뿐이다.
  • 변경을 감지하는 원리?
    1차 캐시저장소에는 본래 엔티티가 아닌, 엔티티에 대한 참조와 복사본인 SnapShot을 가지고있다.
    flush()가 호출되고 실행하기 직전에, EntityManager는 복사복인 SnapShot과 실제 엔티티를 비교하여 값이 다르다면 변경을 감지한다. update
This post is licensed under CC BY 4.0 by the author.