JPA가 등장한 이유는 다음과 같습니다:

  1. 객체 지향 프로그래밍과 관계형 데이터베이스 간의 불일치:
    • 객체 지향 프로그래밍은 상속, 다형성, 연관 관계 등을 통해 복잡한 도메인 모델을 표현할 수 있습니다.
    • 그러나, 관계형 데이터베이스는 테이블, 로우, 컬럼 등의 구조를 가지며, 객체의 상속 구조와는 다른 모델링 방식을 가지고 있습니다.
    • 이로 인해 객체와 관계형 데이터베이스 간의 매핑 작업이 번거롭고 복잡해지는 문제가 있었습니다.
  2. 데이터베이스에 종속적인 SQL 작성:
    • 기존에는 개발자가 SQL을 직접 작성하여 데이터베이스에 접근하는 방식이 일반적이었습니다.
    • 이는 데이터베이스 종류에 따라 SQL 문법과 기능이 달라지는 등의 문제를 야기할 수 있었습니다.
  3. 개발 생산성 향상:
    • JPA는 객체와 데이터베이스 간의 매핑 작업을 자동화하고, 객체 지향적인 코드 작성을 가능하게 함으로써 개발 생산성을 향상시킵니다.
    • 개발자는 객체를 다루듯이 코드를 작성하고, JPA가 데이터베이스와의 매핑을 처리합니다.
    • JPA는 개발자가 직접 SQL을 작성할 필요 없이 객체를 저장, 수정, 조회, 삭제하는 등의 CRUD 작업을 편리하게 수행할 수 있도록 합니다.

SQL은 여러 데이터들을 테이블로 쪼개놓았습니다.

 

하지만 우리는 하나의 테이블에 있는 정보만 요청하는 경우가 거의 없죠.

 

SQL에서 주문 테이블이 있다고 가정을 해봅시다.

 

주문 테이블는 주문정보가 들어있을 것이고, 각 주문 정보 ID를 FK로 한 주문 아이템 리스트 테이블이 있을겁니다.

 

이걸 관계형 데이터베이스를 아는 사람이라면 당연히 조인을 생각하겠지만,

 

관계형 데이터베이스를 모르는 자바 개발자에게 이 정보를 알려주면 어떤식으로 생각을 할까요?

 

주문 정보 안에 주문리스트 아이템? 뭐 쉽네! 하면서

 

public class Order {
    private Long id;
    private String orderNumber;
    private List<OrderItem> items;
    // ...
}

public class OrderItem {
    private Long id;
    private String productName;
    private int quantity;
    // ...
}

이런식으로 클래스를 만들겁니다.

 

그냥 Order 안에 OrderItem을 담는 List 만들어서 넣어주면 끝 아니야?

 

이렇게 패러다임의 불일치가 발생하다보니 SQL만 아는 개발자와 JAVA만 아는 개발자는 말이 통하지 않게 될겁니다.

 

뭐, 그래도 어떻게 둘이 어느정도 합의를 봤다고 가정을 합시다.

 

내가 JAVA코드로 ~~ 이렇게 짜면 SQL 로  ~~ 조인해서 이렇게 짜면 돼. 하고 말이죠

 

근데 이제 테이블이 추가되었습니다. 이번엔 배송정보입니다. 주문의 배송에 관련된 정보들이 들어갑니다.

 

또 그럼 간단하게 DeliveryInfo 객체를 만들어서 Order 안에 리스트로 넣어주도록 합니다.

 

배송 주문자 아이디를 통해 회원 정보도 알 수 있어야 합니다.

 

MemberInfo 객체도 만들어서 Order 안에 넣어주도록 합니다.

 

그럼 이제 Order 안에서 우리는 다양한 정보들을 가지고 올 수 있겠군요.

 

그럼  이제 우리는 객체지향적으로 RDBMS를 구현하였습니다.

 

하지만 Order객체를 하나 가져올 때 우리는 모든 테이블들이 조인된 상태인 쿼리가 필요하게 되었습니다.

 

그렇지 않으면 Order 객체에서 OrderItem을 가져올지 DeliveryInfo를 가져올지, MemberInfo를 가져올지 알 수 없으니 부분만 가져왔다가는 실행이 안되는 경우가 발생하게 될테니까요.

 

RDBMS에서는 필요에 따라 조인을 하지만, 객체지향적으로 짜려고 하니 객체를 생성할 때마다 참...

 

이걸 막기 위해서 객체를 따로 만들면 어떨까요?

 

OrderAndOrderItem

 

OrderAndDeliveryInfo

 

OrderAndOrderItemAndMemberInfo

 

......

 

이런식으로 모든 경우의 수를 객체로 만들어두는건 어떨까요?

 

네... 머리 터지죠... 이런 문제를 보완하고 생산성을 향상시키기 위해 JPA가 나왔다고 합니다.

 

저런 일일이 맵핑해줘야 하는 복잡한 과정들이 있지만 결국 저걸 사용하면 패러다임의 불일치를 해소할 수 있습니다.

 

근데 해줘야하는 작업들이 너무 방대해지기 때문에 저것들을 대신 처리해줄 API가 있으면 참 좋을 것 같아요.

 

그걸 대신 처리해주는 API가 바로 JPA입니다.

 

Django의 Model이 작동하는 방식과 유사하다고 생각하면 이해하기 쉬울 것 같습니다.

 

그리고 Django querySet에서 해당 모델의 objects를 통해 값들을 가져올 때, Lazy 로딩을 하고, 이미 불러왔던 쿼리가 있다면 재사용을 하는 등 다양한 성능 최적화 작업을 해주었는데,

 

JPA도 마찬가지로 그런 작업들을 대신 해줍니다.

 

eager loading도 당연히 지원을 합니다.

 

결국 테이블을 모두 조인해서 가져오지 않고 어떨 때는 lazy loading으로 일일이 접근하고

 

어떨 때는 eager loading으로 조인을 해서 모든 데이터를 가져오기도 합니다.

 

Django를 사용해봤으니 좀 더 쉽게 이해할 수 있는 부분이 많은 것 같습니다.

 

 

 

 

 

 

+ Recent posts