1. JPA 소개
Last updated
Last updated
우리는 관계형디비 세상에 살고 있다.
하지만 우리는 대부분 객체 지향적인 언어를 사용하고, 객체지향적인 코드를 만들어내고 있다.
다시 말해 객체 패러다임을 관계형디비에 넣고 있는 상황이다.
결론부터 말하면 다음과 같은 문제가 있다.
계층형 아키텍처 -> 진정한 의미의 계층 분할이 어렵다.
SQL 에 의존적인 개발을 피하기가 어렵다.
기존 DB 사용 방법은 직접 쿼리를 쳐야하기 때문에, 요구사항이 변경될 경우 연관된 쿼리를 전부 수정해야 한다.
아래 코드에서 멤버는 팀, 주문, 배달이라는 개념을 가지고 있다는 것을 확신하고 코드를 짠 것이다.
하지만, 실제로 멤버 안에 그러한 개념들이 모두 들어있다고 보장할 수 있을까?
코드(memberDAO
)를 전부 살펴보기 전까지는 멤버에 저런 수많은 개념이 있다는 것을 알 수 없다.
객체 지향을 통해 소프트웨어의 복잡성을 낮추어주는 다양한 장치들이 패러다임의 불일치로 인해 다시 개발자가 객체를 관계형디비에 매핑해주는 일을 해야 한다. (SQL Mapper 역할을 개발자가 한다)
관계형디비에는 상속관계가 없다..
예를 들어 아래 구조에서 ALBUM 을 추가한다고 하면 다음과 같은 순서로 추가할 수 있다.
객체 분해
insert into item ...
insert into album ...
그 후 ALBUM 을 조회하면 다음과 같은 순서로 조회할 수 있다.
각각 테이블에 따른 조인 SQL 작성
각각의 객체 생성
상상만 해도 복잡
그래서 DB 저장할 객체에는 상속 관계 안쓴다.
만약 자바 컬렉션에서 추가하고 조회하면?
정말 간단하다.
list.add(item);
list.get(itemId);
언어와 RDBMS 의 패러다임이 다르기 때문에, 고민이 많아지는 것이다.
방향성의 차이
객체는 참조를 사용 : 방향성이 있다. (team 에서 member 를 찾을 수 없다)
테이블은 외래키를 사용 : 방향성이 없다. (team 에서 join 을 통해 member 를 찾을 수 있다)
객체지향 코드에서 객체를 테이블에 맞추어서 모델링을 한다.. (이렇게 해야 쿼리를 쉽게 만들 수 있다..)
객체 다운 모델링은 다음과 같다.
추가는 어찌저찌 할 수 있겠지만,
조회의 경우 조인지옥에 빠져버린다. (코드가 너무 길어진다..)
객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다. (연관관계를 자유롭게 깔 수 있어야 한다)
하지만 쿼리에서 세팅을 해놓지 않았기 때문에, NullPointException
이 발생할 수 있다.
(처음 실행하는 SQL 에 따라 탐색 범위가 결정된다 = 처음 개발자가 만들어놓은 DAO 로직)
이러한 문제를 해결하기 위해서 상황에 따라 동일한 회원 조회 메서드를 여러벌 생성해두면 된다. (하지만 이렇게 하면 경우의 수가 너무 많다;; -> 언제 다 코딩하나?)
모든 객체를 미리 다 로딩할수는 없다..
DAO 에서는 new 를 통해 새로운 객체를 생성해주기 때문에, 레퍼런스가 다르다..
하지만 컬렉션에서 가져오는 값은 같다.. (이런 패러다임의 차이가 있다..)
이전의 패러다임의 불일치를 해결하기위한 기술이다.
자바 진형의 ORM 기술 표준
Object-relational mapping(객체 관계 매핑)
객체는 객체대로 설계
관계형 데이터베이스는 관계형 데이터베이스대로 설계
ORM 프레임워크가 중간에서 매핑
대중적인 언어에는 대부분 ORM 기술이 존재
SQL 중심적인 개발에서 객체 중심으로 개발
생산성
유지보수
패러다임 불일치 해결
성능
데이터 접근 추상화와 벤더 독립성
표준
...
1차 캐시와 동일성(identity) 보장 (같은 트랜잭션 안에서! - 약간의 조회 성능 향상)
트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
지연 로딩(Lazy Loading)