Object와 Relation은 서로 지향하는 패러다임이 너무 다릅니다.
이 차이를 극복하고자 개발자가 많은 시간과 코드를 소비하고 객체 모델링을 포기하고 데이터 중심의 모델로 변합니다.
이 문제를 해결하고자 JPA를 사용합니다.
자바 ORM 기술 표준입니다.
SQL을 개발자 대신 생성해서 DB에 전달, 아래 문제들도 해결해줍니다.
객체는 객체 모델링을 관계형 DB는 관계형 DB 모델링을 하고 이 둘의 맵핑 방법만을 ORM 프레임워크에게 전달해주면 됩니다.
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;
}
객체에서 참조를 사용해서 연관객체를 찾는 것.
위와 같은 설계에서 객체 그래프를 탐색하면 아래와 같이 자유롭게 객체 그래프를 탐색 할 수 있어야 합니다.
객체라면 충분히 가능해야 합니다.
member.getOrder().getOrderItem().getItem().getCategory();
그런데 아래와 같은 쿼리가 실행 됐다면 그것이 가능할까요?
SELECT M.*, T.* FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
SQL을 직접 다루면 객체 그래프를 다룰 수 있습니다.
하지만, 어디까지 사용할지 모르는데 어디서 끊어질지 모르는 객체 그래프를 사용할 순 없습니다.
결국 어디까지 사용 가능한 객체 그래프인지 SQL문을 열어야 개발자는 확인 할 수 있습니다.
JPA는 연관된 객체를 사용하는 시점에서 적절한 SELECT SQL을 실행합니다.
실제 객체를 사용하는 시점까지 DB 조회를 미룬다고 해서 지연 로딩 이라고 합니다.
만약 아래 구문이 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 상속에 대해선 서론에서 자세히 다루지 않으므로 궁금하다면 밑에 참고