2-1. Spring Data JPA

khs·2022년 6월 23일
0

JPA란?

  • JPA는 자바 ORM 기술에 대한 API 표준이다. (ORM이란 'Object Relational Mapping'의 약자로 객체와 관계형 데이터베이스를 매핑해주는 것을 말한다.)

  • 등장 배경

    • 데이터를 관계형 데이터베이스에서 관리하기 위해서 우리는 SQL문을 사용하는데 SQL 중심개발의 문제점은 개발자가 CRUD라고 불리는 INSERT, UPDATE, SELECT, DELETE 문을 작성해서 객체를 관계형 데이터베이스에 넣어주고 가져오는 작업을 하는 것이다. 즉 개발자가 SQL을 매핑하는 역할을 반복해야한다.

    • 또한 객체와 관계형 데이터베이스의 패러다임의 불일치 문제도 있다. 객체를 데이터베이스에 넣기 위해서는 SQL문을 통해 변환해서 저장해야하고, 데이터베이스에서 객체를 꺼내오기 위해서는 복잡한 SQL문을 작성해야 한다.
      참고링크

      => 이를 해결하기 위해 ORM 기술이 등장

JPA 동작 방식

  • 엔티티 : 데이터베이스의 테이블에 대응하는 클래스로 @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 한다.

  • 엔티티 매니저 팩토리 : 엔티티 매니저 인스턴스를 관리하는 주체로 애플리케이션 실행 시 한 개만 만들어지며 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성한다.

  • 엔티티 매니저 : 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공한다.

    영속성 컨텍스트
    - 엔티티를 영구 저장하는 환경
    - 영속성 컨텍스트는 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 논리적 개념
    - 엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다. 엔티티 매니저가 생성되면 논리적 개념인 영속성 컨텍스트가 1:1로 생성된다.

    대표적인 엔티티 매니저 메소드
    - find() 메소드 : 영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장한다.
    - persist() 메소드 : 엔티티를 영속성 컨텍스트에 저장한다.
    - remove() 메소드 : 엔티티 클래스를 영속성 컨텍스트에서 삭제한다.
    - flush() 메소드 : 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영한다.

  • 엔티티 생명주기

생명 주기내용
비영속(new)new 키워드를 통해 생성된 상태로 영속성 컨텍스트와 관련이 없는 상태
ex) Member member = new Member("khs")


영속(managed)- 엔티티가 영속성 컨텍스트에 저장된 상태로 영속성 컨텍스트에 의해 관리되는 상태
- 영속 상태에서 데이터베이스에 저장되지 않으며, 트렌젝션 커밋 시점에 데이터베이스에 반영
ex) Member member = new Member("khs")
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.persist(member); // 이제 영속성 컨텍스트에서 관리

주의 - entityManager.persist(member); 를 한다고 DB에 저장되는 것은 아니고, 커밋 혹은 flush() 이후에 DB에 저장된다. 그 전까지는 영속성 컨텍스트에만 존재


준영속 상태(detached)영속성 컨텍스트에 엔티티가 저장되었다가 분리된 상태
ex) Member member = new Member("khs")
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.detach(member);

참고 - 개발자가 직접 준영속을 만들 일은 거의 없다.


삭제 상태(remove)영속성 컨텍스트와 데이터베이스에서 삭제된 상태
ex) Member member = new Member("khs")
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.remove(member);

  • 영속성 컨텍스트 사용 시 이점!

    • 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트라는 중간계층을 만들면 버퍼링, 캐싱 등을 할 수 있는 장점이 있다.

    • 1차 캐시 : 영속성 컨텍스트에는 1차 캐시가 존재하며 Map<KEY,VALUE>로 저장된다. entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시를 조회한다. 엔티티가 존재할 경우 해당 엔티티를 반환하고, 엔티티가 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환한다.

    • 트렌젝션을 지원하는 쓰기 지원 : 영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재하는데 entityManager.persist()를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소에 SQL문이 저장된다. 이렇게 SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL문들이 flush되면서 데이터베이스에 반영된다. -> 모아서 보내기 때문에 성능에서 이점을 볼 수 있다.

Repository

public interface ItemRepository extends JpaRepository<Item,Long>

JpaRepository는 2개의 제네릭 타입을 사용하는데 첫 번째에는 엔티티 타입 클래스를 넣어주고, 두 번째는 기본키 타입을 넣어준다.

** 참고 : 프로젝트에서 잘 만들어진 테스트 케이스는 유지보수 및 소스코드의 안정성을 위해서 중요하다. 테스트 환경의 경우 h2 데이터베이스를 많이 사용하며 resources 아래에 application-test.properties파일을 만들어서 h2 데이터베이스 설정을 입력해준다.

@TestPropertySource(locations = "classpath:application-test.properties")

테스트를 진행하고자 하는 클래스에 위와 같이 작성해주면 해당 환경에서 테스트가 진행된다.

profile
권혁상입니다. 행복코딩^_^

0개의 댓글