[JPA] JPA 란?

ttaho·2023년 12월 7일
0

JPA

목록 보기
1/7

자바 진영의 ORM(Object-Relational Mapping) 기술 표준인 JPA(Java Persistence API)에 대해 알아보자.

JPA란?

JPA는 자바 진영에서 ORM 기술 표준으로 사용되는 인터페이스의 모음이다. 이 말은, 실제적으로 구현된것이 아니라 구현된 클래스와 매핑을 시켜주기 위해 사용하는 프레임워크 이다. JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있다.

JPA는 애플리케이션과 JDBC 사이에서 동작한다.
즉, JPA를 쓴다해서 JDBC를 사용 안하는것이 아니다!

ORM 이란?

애플리케이션의 Class와 RDB(Relational DataBase)의 테이블을 매핑(연결)한다는 뜻이며, 기술적으로는 어플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것이라고 보면된다.

왜 JPA를 사용해야 할까?

SQL 중심이 아닌 객체 중심으로 개발하기 때문에 생산성이 좋아지고 유지보수가 수월하다.

자세히 알아보자..

이런 테이블 구조에서 Album 클래스를 저장한다고 가정해보자.

// Album 객체저장
jpa.persist(album);

이렇게 하면 JPA는 위의 코드를 아래의 쿼리로 변환하여 실행한다.

INSERT INTO ITEM (ID, NAME, PRICE) .....
INSERT INTO ALBUM (ARTIST) .....

Album을 Insert하게 되면 Album의 부모인 ITEM 객체도 Insert하게 된다.

조회도 마찬가지 이다.

// JAVA 코드
String albumId = "id100";
Album album = jpa.find(Album.class, albumId);
// 변환된 쿼리
SELECT I.*, A.*
  FROM ITEM I
  JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID

자식인 Album 객체를 조회하게되면 부모인 Item 에서도 조회를 수행하게 된다.

다음으로 이런 연관관계를 가진 객체와 테이블에 대해 살펴보자.

Member 클래스가 Team 클래스를 필드로 가지고있다. 코드로 나타내면 아래와 같다.

class Member {
 String id;
 Team team;
 String username;
}


class Team {
 Long id;
 String name;
}

member를 조회하게 되면 team도 가져오게된다.

// JAVA 코드
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();

위 코드는 아래와 같다.

// 변환된 쿼리
SELECT M.*, T.*
 FROM MEMBER M
 JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

살펴본 구조들이 더 복잡해져도 JPA는 문제없이 사용할 수 있다.

JPA의 특징

성능면에서도 JPA는 이점이 있다!

1. 1차 캐시와 동일성 보장

String memberId = "100";
Member member1 = jpa.find(Member.class, memberId); // SQL
Member member2 = jpa.find(Member.class, memberId); // 캐시

member1 == member2; //같다.

JPA는 동일한 트랙잭션에서 조회한 엔티티는 같은 엔티티를 반환한다 -> 약간의 조회 성능 향상

2. 트랜잭션을 지원하는 쓰기 지연 - INSERT

  1. 트랜잭션을 커밋할 때까지 INSERT SQL을 모음.
  2. JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
transaction.commit(); // [트랜잭션] 커밋

3. 트랜잭션을 지원하는 쓰기 지연 - UPDATE

  1. UPDATE,DELETE로 인한 로우(ROW)락 시간 최소화
  2. 트랜잭션 커밋 시 UPDATE, DELETE SQL 실행하고, 바로 커밋
transaction.begin(); // [트랜잭션] 시작
changeMember(memberA); 
deleteMember(memberB); 
비즈니스_로직_수행(); //비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다. 
//커밋하는 순간 데이터베이스에 UPDATE, DELETE SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋

4. 지연 로딩과 즉시 로딩

  • 지연 로딩 : 객체가 실제 사용될 때 로딩
  • 즉시 로딩 : JOIN SQL로 한번에 연관된 객체까지 미리 조회

지연 로딩에서는 team.getNAME 을 할 때 select를 하지만, 즉시 로딩은 find member 할때 다 가져온다!

ETC

추가적으로, 스프링에서 이때까지 사용해왔던 JPA는 JPA를 이용하는 spring-data-jpa 프레임워크이지 JPA는 아니라고 한다.

참조

[Spring JPA] JPA란?

profile
백엔드 꿈나무

0개의 댓글