JPA

JPA의 개념과 이해

hs-archive 2021. 7. 4. 16:58

https://unsplash.com/@picoftasty

spring boot 프로젝트를 하면서

 

데이터 베이스 쿼리를 날리기 위해 JPA를 사용하고 있는데,

 

이해 없이 사용만 하는 것 같아 JPA의 기초적인 개념과 동작에 대해 알아보고자 글을 쓴다.

 

글의 대부분은 아래 유튜브를 보며 정리한 것이고, 강의가 깔끔하여서 웬만하면 강의를 듣는 게 좋겠단 생각이 들었다.

 

 

 

 

 


얻어갈 지식

  • JPA 개념과 장점

 

 

 

 

 

"JPA 란?"

 

 

JPA ( Java persistence API )는 자바 진영의 ORM 기술 표준이다.

 

더보기

ORM 이란?

 

ORM ( Object Relational Mapping - 객체 관계 매핑 )은 테이블을 객체지향적으로 사용하기 위한 기술.

 

Object ( 애플리케이션 쪽 )와 Realational ( RDB ) 간 매핑을 해주는 녀석이다.

 

객체는 객체대로 설계하고, 관계형 데이터베이스는 관계형 데이터베이스대로 설계를 하면 그 중간에서 ORM이 그 둘을 매핑해 준다.

 

ORM

 

 

 

 

 

"JPA 의 장점"

 

 

JPA는 개발자로 하여금 직접적으로 JDBC API를 사용하지 않고,

 

간접적으로 JDBC API를 사용하게 만드는데 ( 아래 그림 참조 )

 

이렇게 함으로써 많은 장점을 얻을 수 있다. 

 

 

 

더보기

JDBC 란?

 

JDBC(Java Database Connectivity)는 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. 

 

JDBC는 데이터베이스에서 자료를 쿼리 하거나 업데이트하는 방법을 제공한다.

 

JPA의 간접적 JDBC 사용 유도

 

1. 생산성 향상

 

쿼리가 자동적으로 생성되므로 쿼리를 따로 만들 필요가 없고,

 

만약 엔티티에 변경이 있더라도 만든 쿼리가 없으므로 수정할 쿼리가 없고 자동으로 변경이 된다.

 

SQL 중심의 개발이 아닌 객체지향 중심의 개발을 가능케 한다.

 

 

 

2. 패러다임의 불일치 해결

 

<연관관계>

Member 객체와 Team 객체가 있을 때

 

RDB에서는 FK를 사용해 이 둘을 연관지어 하나의 테이블로 만들 수 있지만,

 

자바에서는 이처럼 서로 다른 객체를 연관 짓기가 불가능 하다.

 

JPA 는 이러한 문제를 해결해준다.

 

data class Member(
   var id: Long,
   var name: String,
   var team: Team
)

data class Team(
   var id: Long,
   var name: String,
   var memberList: List<Member>
)

 

 

<엔티티 신뢰 문제>

 

Member 엔티티를 DB에서 가져왔을 때

 

해당 member의 어느 레퍼런스까지 채워져 있을까?

 

예를 들어, member 객체 안에 Team, Order 라는 연관된 객체가 있을 때

 

getTeam()이 null이 아니라는걸 확신할 수 있나? 또는,

 

getOrder().getDeliveryTime()이 null 값이 아니라는 확신을 할 수 있을까?

 

JPA는 지연로딩이나 ( 값이 불러질 때 해당 값을 가져오는 쿼리를 날림 ) 즉시로딩 ( 맨 처음 쿼리를 날릴 때 관련된 모든 값을 가져옴 )을 사용해 해당 문제를 해결한다.

 

// 지연 로딩 시
Member member = memberDAO.find(memberId); // SELECT * FROM MEMBER
Team team = member.getTeam();
String teamName = team.getName(); // SELECT * FROM TEAM


// 즉시 로딩 시
Member member = memberDAO.find(memberId); // SELECT M.*, T.* FROM MEMBER JOIN TEAM ...
Team team = member.getTeam();
String teamName = team.getName();

 

 

<JPA 비교하기>

 

JPA는 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장해 준다.

( JPA는 내부적으로 컬렉션처럼 돌아가게 끔 만들었다. 마치 list에 같은 인덱스를 넣어서 얻은 값이 서로 같은 것처럼 )

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

member1 == member2; // 같음

 

 

3. 성능 최적화 기능 제공

 

<1차 캐시와 동일성 보장>

같은 트랜잭션 안에서는 같은 엔티티를 반환 ( 약간의 조회 성능 향상 )

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

member1 == member2; // 같음

 

 

JPA는 처음에는 SQL을 날리지만 두 번 째부터는 캐싱된 데이터를 가져온다.

 

하지만 하나의 트랜잭션 안에서 캐시가 생성되는 거고,

 

해당 캐시를 다른 유저랑 같이 쓰는 게 아니라 혼자 쓰며,

 

트랜잭션이 끝나면 캐시도 사라지기 때문에 큰 성능 향상 기대는 어렵다.

 

 

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

트랜잭션을 커밋할 때까지 INSERT SQL을 모으고 해당 쿼리를 한 번에 전송할 수 있다.

 

transaction.begin(); // 트랜잭션 시작

em.persist(memberA);
em.persist(memberB);
em.persist(memberc);
// INSERT 문을 보내지 않음

transaction.commit() // 이 때 쿼리를 보냄

 

 

 

 

 

"결론"

 

 

JPA는 자바 진영의 ORM 기술 표준이고, 직접 JDBC API를 사용하는 것보다 많은 이점을 제공해 준다.

 

마지막으로 JPA와 ORM, Hibernate 등의 관계를 표현한 그림으로 글을 마치겠다.

 

JPA 관계도

 

 

 

 

 


참고 문서

 

https://www.youtube.com/watch?v=U2s2JhzPZf4 

https://ko.wikipedia.org/wiki/JDBC

 

JDBC - 위키백과, 우리 모두의 백과사전

JDBC(Java Database Connectivity)는 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. JDBC는 데이터베이스에서 자료를 쿼리하거나 업데이트하는 방법을 제공한다. 썬 마이크로시스템즈는 19

ko.wikipedia.org

 

'JPA' 카테고리의 다른 글

JPA N+1 문제 해결  (0) 2023.07.04
QueryDSL  (0) 2023.04.02
JPA 연관 관계 설정  (0) 2021.07.06