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는 인터페이스이며 이를 구현한 대표적인 구현체 :
1) 특정 DB에 종속되지 않음
2) 객체지향적 프로그래밍
3) 생산성 향상
1) 복잡한 쿼리 처리
2) 성능 저하 위험
엔티티
: 데이터베이스의 테이블에 대응하는 클래스
- @Entity가 붙은 클래스는 JPA에서 관리 & 엔티티라고 부른다
- 클래스를 만들고 @Entity 어노테이션을 붙이면 클래스가 엔티티가 된다.
- 클래스 자체나 생성한 인스턴스도 엔티티라고 부름
엔티티 매니저 팩토리
: 엔티티 매니저 인스턴스를 관리하는 주체
- 애플리케이션 실행 시 한 개만 만들어지며, 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성
엔티티 매니저
- 영속성 컨텍스트에 접근해 엔티티에 대한 데이터 베이스 작업을 제공
- 내부적으로 데이터베이스 커넥션을 사용해 데이터베이스에 접근
- 엔티티 매니저의 몇가지 메소드는 아래와 같다
1) find() : 영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 때는 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장
2) persist() : 엔티티를 영속성 컨텍스트에 저장
3) remove() : 엔티티 클래스를 영속성 컨텍스트에서 삭제
4) flush() : 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영
영속성 컨텍스트 Persistent Context
- 엔티티를 영구 저장하는 환경으로, 엔티티 매니저를 통해 영속성 컨텍스트에 접근
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 문 호출할 필요 없음
(+) transient :
jpa dependency를 우리가 추가했기 때문에 엔티티 매니저를 이용해서 직접코드를 작성하지 않아도 됨
대신에 dao 역할을 하는 repository 인터페이스 설계 & 사용
JpaRepository<엔티티타입클래스, 기본키타입>
Jpa레포지토리 : 기본적인 CRUD 및 페이징 처리 위한 메소드가 정의
레포지토리 인터페이스을 작성한 것만으로도 테이블에 데이터 INSERT 하는 것이 가능
Spring Data JPA는 인터페이스만 작성하면 런타임 시점에 Dynamic Proxy 이용해서 객체를 동적으로 생성
find + 엔티티이름 + By + 변수이름
@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