1장 JPA 소개

Object와 Relation은 서로 지향하는 패러다임이 너무 다릅니다.

이 차이를 극복하고자 개발자가 많은 시간과 코드를 소비하고 객체 모델링을 포기하고 데이터 중심의 모델로 변합니다.

이 문제를 해결하고자 JPA를 사용합니다.

JPA란?

자바 ORM 기술 표준입니다.

왜 사용해야 할까?

  • 자바 컬렉션에 객체를 저장하듯 JPA 전달하면 지루한 쿼리들을 JPA가 대신 처리합니다.
  • SQL을 직접 다루면 SQL도 유지보수 해야하지만 JPA는 유지보수 해야하는 코드 수를 줄여줍니다.
  • 아래와 같은 패러다임 문제들을 해결합니다.
  • 한번 조회한 객체를 재사용 할 수 있습니다.
  • DB는 종류에 따라 사용되는 방법이 다릅니다. 즉, DB 벤더에 독립적입니다.

ORM프레임워크란?

SQL을 개발자 대신 생성해서 DB에 전달, 아래 문제들도 해결해줍니다.

객체는 객체 모델링을 관계형 DB는 관계형 DB 모델링을 하고 이 둘의 맵핑 방법만을 ORM 프레임워크에게 전달해주면 됩니다.

SQL을 직접 다룰 때 발생하는 문제점

  • 객체를 데이터베이스에 CRUD 하려면 너무 많은 SQL과 JDBC API를 코드로 작성 해야 한다.
  • 계층 분할이 어려움
    • 컬럼 추가시 CRUD 전체가 다 수정 되어야 한다. ( 엔티티와 SQL의 강한 의존 관계 )
  • 엔티티를 신뢰 할 수가 없음
  • SQL에 의존적인 코드
    • SQL을 숨기려 해도 어쩔 수 없이 SQL에 문제가 없는지 직접 열어서 확인 해야 한다.

패러다임의 불일치

  • DB와 객체지향의 차이
    • 비즈니스 요구사항을 정의한 도메인 모델로 객체를 모델링하고 싶지만 상속, 다형성, 추상화는 DB에 반영 할 수 없다.

JPA와 상속

  • JPA는 상속이 관련된 객체를 DB에서 이용 할 수 있도록 해준다.

JPA와 연관관계

  • 객체는 참조를 이용해 다른 객체와 연관관계를 가지는데 테이블은 FK를 이용해 조인합니다.
    • 객체는 참조만 필요하고 DB는 외래키만 있으면 됩니다.
  • JPA는 객체에 참조 필드를 이용해 FK 조인을 시도합니다.
  • 객체는 참조가 있는 방향으로만 조회가 가능합니다.
    • Member 객체에 Team 객체를 참조했다면 Member에서 Team 조회가 가능하고 반대는 불가능합니다

객체를 테이블에 맞추어 모델링 👎

  • 아래 코드처럼 테이블에 맞춘 객체를 만들면 teamId 부분에서 teamId 를 이용해 다시 조회 해야합니다.
class Member {
	String id;
	Long teamId;     // team id fk 
	String username;
}

class Team {
	Long id;
	String name;
}

객체지향 모델링 👍

  • 그냥 Team team 이렇게 참조를 사용하는게 JPA에선 가능합니다
class Member {
	String id;
	Team team;     // team id fk 
	String username;
}

class Team {
	Long id;
	String name;
}

객체 그래프 탐색이란

객체에서 참조를 사용해서 연관객체를 찾는 것.

Untitled

위와 같은 설계에서 객체 그래프를 탐색하면 아래와 같이 자유롭게 객체 그래프를 탐색 할 수 있어야 합니다.

객체라면 충분히 가능해야 합니다.

member.getOrder().getOrderItem().getItem().getCategory(); 

그런데 아래와 같은 쿼리가 실행 됐다면 그것이 가능할까요?

SELECT M.*, T.* FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

SQL을 직접 다루면 객체 그래프를 다룰 수 있습니다.

하지만, 어디까지 사용할지 모르는데 어디서 끊어질지 모르는 객체 그래프를 사용할 순 없습니다.

결국 어디까지 사용 가능한 객체 그래프인지 SQL문을 열어야 개발자는 확인 할 수 있습니다.

JPA의 객체 그래프 ( 지연 로딩 )

JPA는 연관된 객체를 사용하는 시점에서 적절한 SELECT SQL을 실행합니다.

실제 객체를 사용하는 시점까지 DB 조회를 미룬다고 해서 지연 로딩 이라고 합니다.

데이터 비교 방법

  • DB는 PK로 각 row를 비교 합니다.
  • 객체는 객체 내부 값 비교(동등성), 객체 주소 값 비교(동일성)가 있습니다.

만약 아래 구문이 DB였다면 같은 row, 같은 PK라서 true 였을텐데 객체는 false를 반환합니다.

하지만 JPA는 같은 트랜잭션일 때 같은 객체임을 보장합니다.

// 타 orm
String memberId = "100";
Member member1 = memberDao.getMember(memberId);
Member member2 = memberDao.getMember(memberId);

member1 == member2; //false

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

member1 == member2; //true

이번 장에선 JPA 상속에 대해선 서론에서 자세히 다루지 않으므로 궁금하다면 밑에 참고

댓글남기기