1. JPA 배경
요즘 시대는 객체를 관계형 DB에 관리한다. DB는 SQL 언어만 알아들을수 있어서 코드 보면 다 SQL 언어이므로 관계형 DB를 사용하는 이상 SQL 언어는 피하기가 쉽지 않다.
그리고 SQL 중심적인 개발의 문제점에는 크게 2가지가 있다.
- 자바 객체를 SQL로 SQL을 자바 객체로 → 무한 반복과 지루한 코드
- 패러다임의 불일치
- 관계형 DB = 데이터를 잘 정교화 해서 잘 보관
- 객체 = 필드 ,메서드 잘 갭슐화해서 쓰는게 목표
- → 객체를 관계형DB에 넣으려고 하니 문제 발생
이러한 문제들을 해결하기 위해 JPA가 만들어졌다.
2. JPA 소개
2-1. JPA이란?
JPA(Java Persistence API)는 자바 진영의 ORM 기술 표준으로 자바에서 객체 지향 프로그래밍과 관계형 데이터베이스 간의 데이터를 매핑해주는 표준 API이다. 자바 객체를 데이터베이스의 테이블과 매핑하고, 자바 애플리케이션에서 SQL 없이 데이터베이스 작업을 쉽게 할 수 있게 해준다.
2-2. ORM이란
객체와 관계형 데이터베이스의 테이블 간에 데이터를 변환하는 기법
- Object-relational-mapping(객체 관계 매핑)
- 객체는 객체대로 설계
- 관계형 데이터베이스는 관계형 데이터베이스대로 설계
- ORM 프레임워크가 중간에서 매핑
- 대중적인 언어에는 대부분ORM 기술이 존재
2-3. JPA는 애플리케이션과 JDBC 사이에서 동작
- JPA 동작 - 저장
- JPA 동작 - 조회
2-4. JPA를 왜 사용해야 하는가?
- SQL 중심적인 개발에서 객체 중심으로 개발
- 생산성 - JPA와 CRUD
- 저장: jpa.persist(member)
- 조회: Member member = jpa.find(memberId)
- 수정: member.setName("변경할 이름")
- 삭제: jpa.remove(member)
- 유지보수
- JPA는 필드만 추가하면 SQL은 JPA가 처리하여 SQL문까지 모두 수정했던 과정을 안해도 된다.
= 모든 쿼리를 수정 → DB 컬럼에 추가만
- JPA는 필드만 추가하면 SQL은 JPA가 처리하여 SQL문까지 모두 수정했던 과정을 안해도 된다.
- 패러다임의 불일치 해결
- JPA와 상속
- 상속관계를 일때 INSERT 쿼리를 두번 짜져야되는 경우 → jpa.persist(객체)
- 조회 경우도 조인하여 조회해줌
- JPA와 연관관계
- 객체는 참조
- 테이블은 외래 키
- ⇒ 관계형 데이터베이스의 테이블 간 관계(외래 키) → 객체 지향적
- JPA와 객체 그래프 탐색
- 객체 그래프 탐색: JPA 엔티티 간의 연관관계를 통해 여러 엔티티를 탐색하는 것
- JPA와 비교하기
- 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장
- JPA와 상속
⇒ 직접 SQL을 사용하는 경우
-
-
Member member1 = executeSQL("SELECT * FROM member WHERE id = 1"); Member member2 = executeSQL("SELECT * FROM member WHERE id = 1"); System.out.println(member1 == member2); // false 출력
- ⇒ JPA를 사용할 경우
Member member1 = entityManager.find(Member.class, 1L); Member member2 = entityManager.find(Member.class, 1L); System.out.println(member1 == member2); // true 출력 (같은 객체)
- 데이터 베이스는 매번 데이터를 가져와서 객체를 만들기 때문에, 두 번 조회 하더라도 객체는 서로 다른 인스턴스가 된다. 하지만 JPA는 영속성 컨텍스트 를 통해 동일한 트랜잭션 내에서는 같은 데이터를 두번 조회해도 같은 객체를 반환한다.
- 영속성 컨텍스트는 한 번 조회한 엔티티를 메모리(캐시)에 보관하고, 같은 엔티티를 다시 조회할 때는 캐시된 객체를 반환하기 때문에, 매번 새로운 객체를 만들지 않는다.
-
- 성능
- 1차 캐시와 동일성 보장
- 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상
- DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장(영속성 컨텍스트 덕분)
- 트랜잭션을 지원하는 쓰기 지연
- 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
- JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
- 지연 로딩과 즉시 로딩
- 지연 로딩: 객체가 실제 사용될 때 로딩
- 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회
- ⇒ 애플리케이션 제작시 지연 로딩 코드 작성하고 필요한 부분만 즉시 로딩으로 최적 화
- 1차 캐시와 동일성 보장
- 데이터 접근 추상화와 벤더 독립성
- 표준