스프링부트 쇼핑몰 프로젝트 | 2 JPA

Yunny.Log ·2022년 4월 21일
0

Spring Boot

목록 보기
43/80
post-thumbnail

2.1 JPA

2.1.1 JPA란

JPA, ORM

  • JPA : Java Persistent API

    자바 ORM 기술에 대한 API 표준을 의미

  • ORM : Object Relational Mapping

    객체와 관계형 데이터베이스를 매핑해주는 것

  • 문제점 :

    • sql 중심 개발의 문제점은 개발자가 crud라고 불리는 insert, update, select, delete 문을 작성해서 객체를 RDB에 넣어주고 가져오는 작업을 수행하는 것
    • 자바 객체를 SQL을 통해 데이터베이스에 관리하게 하고 데이터베이스에 지정된 데이터를 자바 애플리케이션에서 사용하게 하기 위해선 SQL 을 통해 다시 자바 객체로 변환하는 반복 작업 필요
      => 개발자가 SQL 매핑을 진행해야 함
  • 객체와 관계형 DB의 패러다임 불일치 존재

  • 이를 해결하기 위한 기술 : ORM

    ORM :
    -객체는 객체지향적으로, 데이터베이스는 데이터베이스대로 설계
    -이후 이 두개를 매핑해주는 것이 ORM의 역할
    -JPA : ORM 기술의 표준 명세, 자바에서 제공하는 API

  • JPA는 인터페이스이며 이를 구현한 대표적인 구현체 :

    • Hibernate
    • EclipseLink

JPA 사용 시 장점

1) 특정 DB에 종속되지 않음

  • DB를 변경하면 쿼리문이 달라서 수정 필요하지만 JPA는 어떤 데이터베이스 사용하는지만 알려준다면 얼마든지 데이터베이스 변경 가능

2) 객체지향적 프로그래밍

  • 데이터베이스 설계 중심의 패러다임에서 객체지향적으로 설계가 가능
    보다 직관적, 비즈니스 로직에 집중 가능

3) 생산성 향상

  • DB테이블에 새로운 컬럼 추가 시, 해당 테이블 컬럼 사용하는 DTO 클래스 필드 모두 변경해야 함
  • 그러나 JPA에선 테이블과 매핑된 클래스에 필드만 추가한다면 쉽게 관리 가능
  • SQL문 직접 작성이 아닌 객체를 사용해 동작해서 유지보수 측면에도 좋고 재사용성 증가

JPA 사용 시 단점

1) 복잡한 쿼리 처리

  • 복잡한 쿼리 사용 경우에는 SQL 문 사용하는 것이 나을 지도,
  • 이를 보완하기 위한 것이 SQL과 유사한 기술인 JPQL

2) 성능 저하 위험

  • 객체 간 매칭 설계 잘못하면 성능 저하 발생 가능
  • 자동 생성 쿼리가 많아서 개발자가 의도하지 않는 쿼리로 인해 성능 저하 가능성 높음

2.1.2 JPA 동작방식

엔티티

: 데이터베이스의 테이블에 대응하는 클래스

  • @Entity가 붙은 클래스는 JPA에서 관리 & 엔티티라고 부른다
  • 클래스를 만들고 @Entity 어노테이션을 붙이면 클래스가 엔티티가 된다.
  • 클래스 자체나 생성한 인스턴스도 엔티티라고 부름

엔티티 매니저 팩토리

: 엔티티 매니저 인스턴스를 관리하는 주체

  • 애플리케이션 실행 시 한 개만 만들어지며, 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성

엔티티 매니저

  • 영속성 컨텍스트에 접근해 엔티티에 대한 데이터 베이스 작업을 제공
  • 내부적으로 데이터베이스 커넥션을 사용해 데이터베이스에 접근
  • 엔티티 매니저의 몇가지 메소드는 아래와 같다
    1) find() : 영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 때는 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장
    2) persist() : 엔티티를 영속성 컨텍스트에 저장
    3) remove() : 엔티티 클래스를 영속성 컨텍스트에서 삭제
    4) flush() : 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영

영속성 컨텍스트 Persistent Context

  • 엔티티를 영구 저장하는 환경으로, 엔티티 매니저를 통해 영속성 컨텍스트에 접근

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

  • JPA가 영속성 컨텍스트를 사용하는 이유
    => 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트라는 중간 계층을 만들었기 때문
  • 애플리케이션과 데이터베이스 사이에 이와 같이 중간계층을 만들게 되면 버퍼링, 캐싱 등을 할 수 있는 장점이 존재

1차 캐시

  • 영속성 컨텍스트에는 1차 캐시가 존재
  • Map<KEY, VALUE>로 저장
  • entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시 조회
  • 엔티티가 존재하지 않으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환

동일성 보장

  • 하나의 트랜잭션에서 같은 키 값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장
  • 바로 1차 캐시에 저장된 엔티티 저장하기 때문에 가능

트랜잭션을 지원하는 쓰기 지연

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

변경 감지

  • JPA는 1차 캐시에 데이터베이스에서 처은 불러온 엔티티의 스냅샷 값을 가진다.
  • 그리고 1차 캐시에 저장된 엔티티와 스냅샷을 비교후 변경 내용 존재하면 UPDATE SQL문을 쓰기 지연 SQL저장소에 담아둠
  • 그리고 DB에 커밋 시점에 변경 내용을 자동으로 반영 => 따로 update 문 호출할 필요 없음

2.3 Entity 설계

(+) transient :

2.4 Repository

  • jpa dependency를 우리가 추가했기 때문에 엔티티 매니저를 이용해서 직접코드를 작성하지 않아도 됨

  • 대신에 dao 역할을 하는 repository 인터페이스 설계 & 사용

  • JpaRepository<엔티티타입클래스, 기본키타입>

  • Jpa레포지토리 : 기본적인 CRUD 및 페이징 처리 위한 메소드가 정의

  • 레포지토리 인터페이스을 작성한 것만으로도 테이블에 데이터 INSERT 하는 것이 가능

  • Spring Data JPA는 인터페이스만 작성하면 런타임 시점에 Dynamic Proxy 이용해서 객체를 동적으로 생성

2.5 쿼리 메소드

  • JPA : 레포지토리 인터페이스에 간단한 네이밍 룰을 이용해 메소드를 작성하면 원하는 쿼리 실행 가능
  • 쿼리 메소드 이용 시 가장 많이 이용하는 문법으로 FIND 사용

find + 엔티티이름 + By + 변수이름

2.6 Spring Data JPA @Query 어노테이션

  • 조건이 많아지는 복잡한 쿼리는 직접 작성 needed
  • JPQL : 엔티티 객체 대상으로 쿼리 수행
  • 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리
  • JPQL은 SQL을 추상화해서 사용, 특정 데이터베이스 SQL에 의존하지 않음
  • JPQL로 작성했다면 데이터베이스가 변경돼도 애플리케이션이 영향받지 않음

2.7 Spring DATA JPA QueryDSL

  • @Query : 문자열 형식으로 문자열을 입력, 컴파일시점에 에러 발견 불가능

  • @QueryDsl
    : JPQL을 코드로 작성하게 도와줌 => 컴파일러의 도움을 받게 해줌

  • 오타 발생하면 오타 알려줌

장점

  • 고정된 SQL문이 아닌 조건에 맞게 동적으로 쿼리 생성 가능
  • 비슷한 쿼리를 재사용 가능, 제약조건 조립, 가독성 향상 가능
  • 문자열이 아닌 자바 소스코드로 작성하기 때문에 컴파일 시점에 오류 발견 가능
  • IDE 도움 받아 자동완성 기능 이용할 수 있어서 생산성 향상 가능


학습 내용 , 이미지 출처 및 참고 책 : 백견불여일타 스프링 부트 쇼핑몰 프로젝트 with JPA https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=278601116
참고 블로그 : https://incheol-jung.gitbook.io/docs/study/jpa/6#n-n

0개의 댓글