Jdbc를 사용하고, 아래의 구조를 가진 애플리케이션이 있다고 생각해보자.
한 노선에 포함된 모든 지하철 구간의 정보를 얻어오고 싶다. 하지만 Section 테이블에서 값을 조회하는 경우 아래와 같은 객체가 나올 것이다.
public class Section {
private Long id;
private Long lineId;
private Long upStationId;
private Long downStationId;
private int distance;
// ...
}
이런 경우 각 lineId, upStationId, downStationId를 통해 Line 테이블, Station 테이블에서 데이터를 가져와야한다. 또한 우리가 원하는 구조는 이런 구조가 아니다. 이것은 객체 지향적이지 못하며 db의존적이다.
우리는 조회를 했을 때 아래와 같은 객체를 얻길 바란다.
public class Section {
private Long id;
private Line line;
private Station upStation;
private Station downStation;
private int distance;
// ...
}
이렇게 객체와 db는 차이가 있을 수 밖에 없다. db는 철저히 데이터 중심으로 설계되어 있으며 객체와 db는 목적이 다르다. 패러다임의 불일치는 이렇게 객체(OOP)와 관계형 DB의 데이터 표현방식과 다루는 방법이 달라 일어나는 현상이다.
객체와 db 양쪽의 불일치를 해결해줘야 한다. 그렇지 않다면, db에 의존적이게 코딩을 하게 될 수 밖에 없다.
Repository와 Dao 계층을 둘 다 사용하면 어느 정도 패러다임 불일치를 해결할 수 있다.
Dao의 경우 테이블과 1대1로 매칭되는 클래스라고 생각할 수 있다. 즉 직접적인 데이터 접근의 역할을 한다.
Repository의 경우는 Dao보다 살짝 앞단에서 여러 Dao를 가지고 데이터를 조합해서 필요한 도메인으로 만들어 Service단에 전달해 줄 수 있다. 즉 한 단계 더 캡슐화 했다고 생각할 수 있다.
즉 Service - Repository - Dao
의 형태가 나온다.
각 Dao는 매핑되는 테이블과만 소통을 하며 데이터를 직접 가져온다. Repository단에서 가져온 데이터를 조합하여 엔티티로 만들어주고 Service단으로 보내준다. Dao는 Data Access 계층에 속하고, Repository는 Domain과 Data Access 계층 사이에 속한다고 볼 수 있다. 이런식으로 Repository가 중간에서 데이터를 객체로 매핑해주면서 패러다임 불일치를 없애준다.
좀 더 쉽게 생각하면 Dao는 테이블을 위한 것이며 좀 더 저수준에 가까운 개념이고, Repository는 객체를 위한 것이며 좀 더 상위 수준의 개념이라고 볼 수 있다.
따라서 위의 Section을 가지고 예시를 들어보려고 한다.
결국 SectionRepository는 Section 엔티티를 위한 것이고, SectionDao는 Section 테이블을 위한 것이라고 생각할 수 있다.
SectionDao를 통해 테이블을 위한 id, lineId, upStationId, downStationId, distance를 받아와서 SectionRepository에서 LineDao, StationDao로 각 id값을 보내서 데이터를 조회해오고, 완전한 Section 엔티티로 만들어서 내보내준다.
그렇지만 실제로는 Repository와 Dao를 동일시하여 하나만 사용하는 곳이 많다고 한다. 따라서 이런 경우는 그냥 Repository라고 명명하고 join쿼리를 쓰거나 하는 방식으로 사용한다.
그러나 이런식으로 직접 매핑해주는 작업은 개발자의 비용이다. JPA는 영속성 컨텍스트를 통해 개발자 대신 이런 패러다임 불일치를 해결해준다.
JPA를 사용한다면 영속성 컨텍스트를 통해 객체와 RDB 사이의 패러다임 불일치를 해결할 수 있다. JPA란 Java Persistence API 의 약어로 자바진영의 ORM 기술 표준을 말한다. 구현체로는 Hibernate, EclipesLink, dataNucleus가 있다.
영속성(persistence)은 데이터를 생성한 프로그램이 종료되더라도 사라지지 않는 데이터의 특성을 의미한다.
영속성 컨텍스트는 엔티티를 영구히 저장하는 환경이라는 뜻. 애플리케이션과 DB 사이에서 객체를 보관하는 가상의 DB 역할을 한다. Entity Manager를 통해 엔티티를 저장하거나 조회하면, Entity Manager는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
엔티티가 영속성 컨텍스트에 저장되고 DB와 통신을 하게되는 구조를 가진다. 객체지향 적인 부분을 JPA가 db에 맞게 바꿔 처리해준다.
영속성 컨텍스트는 엔티티를 식별자로 구분한다. 따라서 반드시 식별자가 있어야한다.
(자세한 내용은 JPA를 사용하게 됐을 때 추가하기)
DAO vs Repository Patterns
JPA - 영속성 컨텍스트
패러다임 불일치를 해결하는 하이버네이트의 필수 개념정리 (ORM은 무엇인가 그리고 왜 사용하는 가?, 영속성(Persistence), 영속성컨텍스트 정의 포함)
[JPA] 패러다임 불일치
3. [JPA] 영속성 컨텍스트란?
JPA 영속성 컨텍스트란?