JPA란 무엇인가?

Moon·2022년 8월 1일
0
post-thumbnail

JPA (Java Persistent API)

자바 진영의 ORM 기술 표준으로 자바 애플리케이션과 JDBC 사이에서 동작한다.

💡ORM (Object Relational Mapping)

  • JPA의 등장 배경에서 계속 언급했던 객체와 관계형DB를 매핑하는 것이 ORM이다.
  • ORM 프레임워크는 개발자 대신 객체와 테이블을 매핑해서 패러다임 불일치 문제를 해결한다.

저장

jpa.persist(member);
  • 객체를 저장하고 싶으면 MemberDAO가 JPA에게 member 객체를 넘긴다.
  • JPA가 member객체를 분석해서 적절한 INSERT SQL을 생성한다.
  • JPA는 JDBC API를 사용해서 INSERT 쿼리를 보내고 결과를 받는다. (객체 저장)

조회

Member member = jpa.find(memberId);
  • JPA에 PK값만 넘기고 원하는 member객체를 달라고 한다.
  • JPA는 member 객체를 보고 적절한 SELECT 쿼리를 만들어 JDBC API를 통해 DB에 보낸다.
  • Resultset을 매핑해서 DAO에 객체를 전달해준다.

🙂 왜 JPA를 사용할까?

✔️ 생산성

JPA로 CRUD를 하려면 이미 만들어진 코드를 쓰기만 하면 되기 때문에 너무 간단하다.
위의 저장과 조회에 대한 설명에서도 봤듯이 내부의 동작들이 코드 한 줄로 해결된다.

// 저장
jpa.persist(member)

// 조회
Member member = jpa.find(memberId)

// 수정
member.setName("변경할 이름")

// 삭제 
jpa.remove(member)

✔️ 유지보수

개발자가 직접 작성해야 했던 코드를 JPA가 대신 처리해주므로 유지보수가 훨씬 쉬워진다.

기존의 SQL에 의존적인 개발에서는 필드 하나를 추가하더라도 관련된 등록, 수정, 조회, SQL 매핑을 위한 JDBC API 코드를 모두 변경해야 했다. JPA를 사용하면 이런 과정을 JPA가 알아서 처리해준다.

✔️ JPA와 패러다임의 불일치 해결

JPA의 상속

Item의 자식 객체인 Album을 조회하는 경우를 보자.

  • 개발자가 할 일
Album album = jpa.find(Album.class, albumId);
  • 나머지는 JPA가 처리
SELECT I.*, A.*
  FROM ITEM I
  JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID

연관관계

  • 자바 컬렉션에 값을 저장하는 것처럼 사용할 수 있다.
member.setTeam(team);
jpa.persist(member);

객체 그래프 탐색

  • JPA에는 지연로딩이라는 기능이 있어서 자바 컬렉션에서 값을 가져오는 것처럼 사용할 수 있다. (코드가 실행될 때 조회쿼리를 날리기 때문에 객체 그래프를 자유롭게 탐색할 수 있음)
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
Delivery delivery = member.getOrder().getDelivery()

✔️ 성능과 최적화 기능

1차 캐시와 동일성 보장

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

println(m1 == m2) //true

SQL을 한 번만 실행해도 된다. 같은 트랜잭션 안에서는 같은 엔티티를 반환하기 때문에 조회 성능이 약간 향상된다.

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

  • 트랜잭션을 커밋할 때까지 INSERT SQL을 모았다가 커밋하는 순간에 한꺼번에 전송한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);

transaction.commit(); // 커밋하는 순간 INSERT SQL문 한꺼번에 전송됨 

지연로딩 / 즉시로딩

  • 지연로딩 : 객체가 실제 사용될 때 로딩
Member member = memberDAO.find(memberId);
Team team = member.getTeam();
String teamName = team.getName();
SELECT * FROM MEMBER
SELECT * FROM TEAM

👉 지연 로딩은 쿼리가 많이 나가기 때문에 멤버를 조회할 때 팀을 항상 같이 사용해야 한다면 한 번에 가져오기 위해 즉시로딩을 사용할 수 있다.

  • 즉시로딩 : JOIN SQL로 한 번에 연관된 객체까지 조회함
Member member = memberDAO.find(memberId);
Team team = member.getTeam();
String teamName = team.getName();
SELECT M.*, T.*
FROM MEMBER
JOIN TEAM …

참고 )
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 김영한님 강의
자바 ORM 표준 JPA 프로그래밍 (김영한)

profile
매일 성장하는 개발자 되기😊

0개의 댓글